redis 锁超时自动释放 导致的多客户端同时获取锁 如何解决

假设
客户端1:

通过 `SET lock 123 NX PX 30000`获取了锁
执行时间超时太长, 锁自动失效
但此时客户端1还是在继续执行
....

客户端2:

在客户端1超时导致锁自动失效后, 它立刻获取了锁 `SET lock 456 NX PX 30000`

此时就有两个客户端同时都能执行那些只有获取了锁之后才能执行的内容!!!

阅读 7.4k
4 个回答

使用 WATCH/MULTI/EXEC ,watch能保证 MULTI 和 EXEC 之间的命令只有在watch的值没有变化才执行成功,见官方文档https://redis.io/topics/trans...

所以一般这个锁的值要在整个系统保持唯一。

锁超时被释放不是很正常吗。。 因为我没有用过redis,所以对于楼上说的超时如何避免我不知道。。但是从分布式系统的角度来分析这个问题,锁其实就等于租约,谁从redis得到了租约,谁就是集群的leader,执行一些follower不能做的操作,但是呢,leader总是会由于种种问题(网络、gc)无法及时续租,导致超时,这时候另外一个follower进而得到锁,导致集群双主。 所以问题的性质就变成了分布式情况下如何避免多主(或脑裂)。常用的做法就是fencing机制,如kafka的epoch。楼主可以试下

使用redis做锁时,不应该完全使用超时时间来控制锁是否被占用。
在逻辑执行完后,应该立刻清掉该key释放掉锁,一般写在finally块中保证能够释放。
而超时时间的设置,只是为了万一在逻辑执行过程中系统直接挂掉,没能在最后手动释放锁,又没有超时时间,就会导致该锁永远被占用。
所以,超时时间可以根据该逻辑的执行时间多加大一点进行设置,然后在逻辑执行完之后手动解锁。

不是说redis是单线程 同时间内一次只能处理一条命名 那获取锁的命名单一时间内应该都是唯一 为什么还会出现同时获得的情况,不是很理解,有帮忙解释一下的么 = =~

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题