RedLock存在的问题

自己总结的RedLock的问题:

问题1: 宕机重启之后,2个客户端拿到同一把锁。

假设5个节点是A, B, C, D, E,客户端1在A, B, C上面拿到锁,D, E没有拿到锁,客户端1拿锁成功。 此时,C挂了重启,C上面锁的数据丢失(假设机器断电,数据还没来得及刷盘;或者C上面的主节点挂了,从节点未同步)。客户端2去取锁,从C, D, E 3个节点拿到锁,A, B没有拿到(还被客户端1持有),客户端2也超过多数派,也会拿到锁。
解决方案- 延迟重启;但是由于时钟跳变的因素,导致延迟重启时效(无法解决该问题);

问题2:脑裂问题:就是多个客户端同时竞争同一把锁,最后全部失败。

比如有节点1、2、3、4、5,A、B、C同时竞争锁,A获得1、2,B获得3、4,C获得5,最后ABC都没有成功获得锁,没有获得半数以上的锁。官方的建议是尽量同时并发的向所有节点发送获取锁命令。客户端取得大部分Redis实例锁所花费的时间越短,脑裂出现的概率就会越低。
需要强调,当客户端从大多数Redis实例获取锁失败时,应该尽快地释放(部分)已经成功取到的锁,方便别的客户端去获取锁,假如释放锁失败了,就只能等待锁超时释放了

问题3:效率低,主节点越多,获取锁的时间越长;

其它博客总结的问题:

问题1: 宕机重启之后,2个客户端拿到同一把锁。

假设5个节点是A, B, C, D, E,客户端1在A, B, C上面拿到锁,D, E没有拿到锁,客户端1拿锁成功。 此时,C挂了重启,C上面锁的数据丢失(假设机器断电,数据还没来得及刷盘)。客户端2去取锁,从C, D, E 3个节点拿到锁,A, B没有拿到(还被客户端1持有),客户端2也超过多数派,也会拿到锁。
解决方案- 延迟重启

问题2: 时钟跳跃

刚上面讨论的方案严格依赖时钟,而5台机器上面的时钟是可能有误差的。
时钟跳跃的意思就是:实际时间只过了1s钟(假设),但系统里面2次时间之差可能是1分钟,也就是系统之间发生了跳跃。发生这种情况,可能是运维人员认为修改了系统时间。

时钟跳跃会产生2个后果:
(1)延迟重启机制失效。时钟跳跃可能导致机器挂了立马重启,从而出现上面的问题。
(2)时钟跳跃导致客户端拿到锁之后立马失效。endTime - beginTime 差值太大。这虽然不影响正确性,但影响拿锁的效率。

那么时钟回拨呢?endTime - beginTime会成为负值,不影响算法的正确性。

问题3: 客户端大延迟(比如full GC),2个客户端拿到同一把锁。

理论上,一切有超时强制释放机制的锁,都可能产生这个问题。服务端把锁强制释放了,但是客户端的代码并没有执行完,卡在了某个地方(比如full GC,或者其它原因导致进程暂停),这把锁被分配给了另外一个客户端。

针对这个问题,Redis又提出了watch dog机制。大致意思就是,锁快要到期之前,发现客户端业务逻辑还没执行完,就给锁续期,避免锁被强制释放,分配给另外一个客户端。但是,锁续期本身是个网络操作,也没办法保证续期一定成功!

从这个案例中,可以得到2个重要启示:

(1)在分布式系统中,严格依赖每台机器本机时钟的算法,都可能有风险。
(2)一切具有“超时强制释放机制”的锁,都可能导致客户端还在持有锁的情况下,锁被强制释放。

另外一篇博客给出的答案

1、脑裂问题:就是多个客户端同时竞争同一把锁,最后全部失败。

比如有节点1、2、3、4、5,A、B、C同时竞争锁,A获得1、2,B获得3、4,C获得5,最后ABC都没有成功获得锁,没有获得半数以上的锁。官方的建议是尽量同时并发的向所有节点发送获取锁命令。客户端取得大部分Redis实例锁所花费的时间越短,脑裂出现的概率就会越低。
需要强调,当客户端从大多数Redis实例获取锁失败时,应该尽快地释放(部分)已经成功取到的锁,方便别的客户端去获取锁,假如释放锁失败了,就只能等待锁超时释放了

2、假设一共有5个Redis节点:A, B, C, D, E:

  1. client1锁住A、B、C,没有锁D、E
  2. C数据没有持久化就崩溃重启
  3. client2锁住了C、D、E,获取锁成功
    解决方案:C崩溃后延时重启,延时时间大于锁的过期时间

3、假设一共有5个Redis节点:A, B, C, D, E:

客户端1从Redis节点A, B, C成功获取了锁(多数节点)。由于网络问题,与D和E通信失败。
节点C上的时钟发生了向前跳跃,导致它上面维护的锁快速过期。
客户端2从Redis节点C, D, E成功获取了同一个资源的锁(多数节点)。
客户端1和客户端2现在都认为自己持有了锁。

选用分布式锁时需要明确用途:

  1. 提升效率:避免一个任务被执行两次。但是就算执行了两次也不会出现致命问题
  2. 保证正确:一定要保证数据正确,不允许出现重复执行的情况
    · 假如是为了提升效率而使用锁,则使用单机模式就足够了
    · 假如是需要保证绝对的正确,redlock并不能达到目的。应该考虑类似Zookeeper的方案,或者支持事务的数据库。
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值