分布式锁的进化过程

本文探讨了使用Redis Setnx作为锁的实现中遇到的问题,如锁的原子性、超时时间设置、并发冲突和一致性保证。作者提出通过编号、Lua脚本和定期更新过期时间来改进,涉及技术包括Redis操作、分布式锁策略和一致性算法。
摘要由CSDN通过智能技术生成

思维导图

使用setnx 来作为锁的底层实现

Redis Setnx(SET if Not eXists) 命令在指定的 key 不存在时,为 key 设置指定的值。

如果设置成功返回1,设置失败返回0。

case1  拿到锁 执行代码 但是如果此时应用服务器宕机就完了。因为缓存服务器里这个锁一直在,别的请求都卡死了。
case2 拿到锁 设置超时时间 然后执行代码 
   存在两个问题 
   问题A:设置超时时间和获取锁 得原子性完成
   问题B: 如果超时时间到了 任务还没有完成 怎么办?

先看问题B,这里自行看,也有两个问题
   假如 a 先获得锁 设置十秒过期 a运行完成需要15s
   b在第十秒拿到了锁 此时两个线程都拥有锁(问题C)
   等到第15s,a删除了锁,此时b相当于没有锁的保护了,谁想进来就都能进来(问题D)

咱们先解决第问题D  
   等到第15s,a删除了锁,此时b相当于没有锁的保护了,谁想进来就都能进来
   给每个锁加一个编号,a拿到锁的时候,就设置编号,删除的时候,就只删除自己的锁
   这样一来,第十秒的时候,a的那个锁的编号已经变成b设置的了
   到第15s,a先拿到当前锁的值,然后和自己的编号比较 如果一样,再删除,这样就不会把b的锁删掉了。

   这里还有一个问题
   a先拿到当前锁的值,然后和自己的编号比较 如果一样,再删除
   上面这段话没办法做到一致性
   那怎么办?使用 Lua脚本(其实使用Lua脚本也解决了问题A)

但是到目前为止,还有上面说的问题C
   b在第十秒拿到了锁 此时两个线程都拥有锁
   那怎么办?a获取锁的时候,把超时时间设置到20s?那假如a运行需要25s呢?
   请问,那锁的自动释放时间设置到多少毕竟合适呢?
   有人回答是:根据系统自行设计。。。
   我去,这不相当于没说!
   那怎么办?咱们回忆一下,为什么要给锁设置超时时间?是怕我忽然宕机了,那个锁永远不删除,就卡死了。
   那这样行不行,我拿到锁的时候,就不设置过期时间,然后每隔10s,另一个逻辑模块给redis发请求,把锁的过期时间设置为30s之后。
   这样一来,如果我的服务器突然挂了,最多30s锁也就自动被清理了。
   那怎么实现每隔10s,就去发请求,设置新的过期时间呢?
   请参见Redission

   我还有一个问题,那锁不设置过期时间,如果我的方法真的执行了100s或者更久怎么办?这不是卡死了别的现场?
   如果你的方法真的执行了100s,与其让别的线程进来破坏了数据一致性,还不如让别的卡死呢!
   另外如果你的方法真的执行了100s,你是不是该反思一下,是不是哪些逻辑没有设置超时时间

参考资料:

Redis Setnx 命令 | 菜鸟教程

Redis 分布式锁|从青铜到钻石的五种演进方案 - 悟空聊架构的个人空间 - OSCHINA - 中文开源技术交流社区

关于RedissonLock的一些所思_程序员小董的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值