redis分布式锁redlock算法问题的一些思考

单节点锁,主从拷贝模式下的锁失效问题:

1.客户端A从master上获取了锁。

2.master在将锁所用的key同步到slave之前发生崩溃。(即redis以异步方式进行备份)

3.slave转变成为master。

4.此时客户端B发送请求获取锁,并且成功获取。但是此时客户单A同样拥有此锁,违背了排他性原则,也即不正确了。

 

锁过期问题

 

RedLock中,为了防止死锁,锁是具有过期时间的。

  • 如果 Client 1 在持有锁的时候,因为某种原因发生了一次很长时间的 堵塞 ,超过了锁的过期时间。锁就被释放了。
  • 这个时候 Client 2 又获得了一把锁,提交数据。
  • 这个时候 Client 1 从 堵塞 中苏醒过来了,又一次提交数据。

对于这个问题,主要原因是锁过期了,客户端没法感知。目前貌似没有很好的解决方案。

这里给一个一个可以参考的规避方案,问题的根源就是锁过期了,那么只要我们给锁延长过期时间就可以减缓这个问题,例如我们可以像redisson方案那样启动一个后台线程,定期检查,一般是每隔锁TTL/3(锁过期时间的三分之一)的时间检查一次如果锁还在就自动给这个锁延长过期时间。但是这个方案也没有解决这个问题,只是减少了这个问题出现的概率。

时钟引起的问题

RedLock 是一个 严重依赖系统时钟 的分布式系统。

还是这个过期时间的小辫子。如果某个 Redis Master的系统时间发生了错误,造成了它持有的锁提前过期被释放。

  • Client 1 从 A、B、D、E五个节点中,获取了 A、B、C三个节点获取到锁,我们认为他持有了锁
  • 这个时候,由于 B 的系统时间比别的系统走得快,B就会先于其他两个节点优先释放锁。
  • Clinet 2 可以从 B、D、E三个节点获取到锁。在整个分布式系统就造成 两个 Client 同时持有锁了。

对于这个问题,系统时间的阶跃一般主要来自两个方面:

  • 人为修改。
  • 从NTP服务收到了一个跳跃时时钟更新。

第一种情况,没有什么好的解决方案。

第二种情况,则需要通过运维来保证。需要将阶跃的时间更新到 服务器 的时候,应当采取渐进式小步快跑的方式。多次修改,每次更新时间尽量小。

 性能问题

由于redlock算法需要向多个节点挨个申请锁,必然会导致性能下降。所以对于安全要求不是很高的话使用单节点锁就可以。

如果某些场景需要很高的并发性,一个行之有效的方案是降低锁的粒度。 比如对资源进行分段等。比如考虑这样一种场景,一个商品有1万存货,我们可以把它分成10段,每段一千存货,然后用十个锁来分别保护。这样效率,并发性就会比只用一个锁好很多。 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值