面试连环炮系列(十九):分布式锁的实现方案

  1. 分布式锁的实现方案?
    相比单例锁,分布式锁需要解决的问题:

    • 互斥性:任意时刻只能有一个客户端拥有锁,不能同时多个客户端获取。
    • 安全性:锁只能被持有该锁的用户删除,而不能被其他用户删除。
    • 死锁:获取锁的客户端因为某些原因而宕机,而未能释放锁,其他客户端无法获取此锁,需要有机制来避免该类问题的发生。
    • 容错:当部分节点宕机,客户端仍能获取锁或者释放锁。

    常用的方案是基于Redis集群的锁实现,常用的Java组件是Redission。它对Redis分布式锁的实现非常完善,实现可重入锁、读写锁、公平锁、信号量、CountDownLatch等很多种复杂的锁的语义,满足我们对分布式锁的不同层次的需求。

  2. 主从模式下节点宕机可能导致锁失效,Redission怎么解决的
    Redission实现了Redlock算法解决这个问题。

  3. 说说Redlock算法的原理
    假设我们有5个Redis master实例:

    1. 客户端获取服务器当前的的时间t0,毫秒数。
    2. 使用相同的key和value依次向5个实例获取锁。客户端在获取锁的时候自身设置一个远小于业务锁需要的持续时间的超时时间。举个例子,假设锁需要10秒,超时时间可以设置成比如5-50毫秒。这个避免某个Redis本身已经挂了,但是客户端一直在尝试获取锁的情况。超时了之后就直接跳到下一个节点。
    3. 客户端通过当前时间(t1)减去t0,计算获取锁所消耗的时间t2(t1-t0)。只有t2小于锁的业务有效时间(也就是第二步的10秒),并且,客户端在至少3(5/2+1)台上获取到锁我们才认为锁获取成功。
    4. 如果锁已经获取,那么锁的业务有效时间为10s-t2。
    5. 如果客户端没有获取到锁,可能是没有在大于等于N/2+1个实例上获取锁,也可能是有效时间(10s-t2)为负数,我们就尝试去释放锁,即使是并没有在那个节点上获取到。
  4. Redlock算法有什么缺点吗?
    时间偏差在分布式系统中很常见,在锁有效时间里虽然减去了时钟偏移,但是这个值不太好确定。Redis作者也建议对锁互斥的安全性要求高的应用不要使用这个算法。

参考(部分摘抄的文字版权属于原作者):

https://www.jianshu.com/p/47fd7f86c848
https://www.jianshu.com/p/2d3bf2ff2315
https://www.cnblogs.com/sheldon-lou/p/11039795.html
https://www.cnblogs.com/luocaodan/p/10949558.html

posted @ 2019-10-16 11:14  编码砖家  阅读(335)  评论(0编辑  收藏