利用Redis实现分布式锁

2017-12-30 20:05:59来源:CSDN作者:u010180339人点击

分享

最简单的思路,就是利用到redis的key,这个key的名字可以叫xx_lock。

  • key已存在 -> 锁被占用
  • 创建key -> 获取锁
  • 删除key -> 释放锁

在需要同步的代码里加锁,先去判断有没有这个key,如果有这个key,说明拿不到锁,如果没有,则创建key,表示拿到了锁。在执行完需要同步的代码后,将key删掉释放锁。

基本逻辑就这样,看起来很简单。

但是会有如下几个问题:
1. 加锁: 判断key和创建key,是2个步骤,非原子性,会有race condition
2. 如果持有锁的客户端挂了,这个key就永远不会被删除,即永远不会解锁

问题1解决方案: redis的set有nx参数,只有key不存在的时候才能设置成功,这样就保证了原子性
问题2解决方案: 可以加个超时时间,到期自动删除.

问题2的解决方案,又会引出新的问题。即误删问题。当持有锁的A阻塞了很久,key到期自动被删除了,这时B又创建了锁,然后A从阻塞中恢复,把B创建的key给删除了。
解决方案: 给key设一个随机数value,当要删除key释放锁的时候,先匹配一下随机数,确定是自己创建的锁才释放掉。

这时又引出一个新问题,匹配随机数和删除key是2个步骤,非原子性,会有race condition
解决方案: 用lua脚本来确保原子性。
示例代码

if redis.call("get",KEYS[1]) == ARGV[1]then    return redis.call("del",KEYS[1])else    return 0end

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台