可能是全站最完整的Redis分布式锁架构演进

2020-05-27 10:32:14 浏览数 (1)

  • 厕所占坑原理

已经拿到了 lockvalue ,有了 UUID,但是过期了现在!其他人拿到所锁设置了新值,于是 if 后将别人的锁删了!!也就是删除锁不是原子操作。

  • 确保加锁,解锁都原子性。

官方叫做RedLock算法,是Redis官方支持的分布式锁算法.

这个分布式锁有3个重要的考量点

  • 互斥(只能有一个客户端获取锁)
  • 不能死锁
  • 容错(大部分Redis节点或者这个锁就可以加可以释放)

3.1 最普通的实现方式

创建一个key

代码语言:javascript复制
SET my:lock 随机值 NX PX 30000
  • NX : 只有key不存在的时候才会设置成功
  • PX 30000 : 30秒后锁自动释放。别人创建的时候如果发现已经有了就不能加锁了.

释放锁就是删除key,但是一般可以用lua脚本删除,判断value一样才删除:

关于redis如何执行lua脚本,自行百度

代码语言:javascript复制
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
    return 0
end

为啥用随机值呢? 因为如果某客户端获取锁,但阻塞了很长时间才执行完,此时可能已经超时释放锁了,可能别的客户端已经获取到了锁,要是此时你直接删除key会有问题,所以得用随机值加上面的lua脚本来释放锁.

但是这样是肯定不行的

  • 如果是普通的Redis单实例,那就是单点故障
  • 是Redis普通主从,那Redis主从异步复制,如果主节点挂了,key还没同步到从节点,此时从节点切换为主节点,别人就会拿到锁.
  • Redis最普通的分布式锁的实现原理

3.2 RedLock算法

假设有一个redis cluster,有5个redis master实例. 执行如下步骤获取锁:

  1. 获取当前时间戳(ms)
  2. 尝试轮流在每个master节点创建锁,过期时间较短(几十ms)
  3. 尝试在大多数节点建立一个锁,比如5个节点就要求是3个节点(n / 2 1)
  4. 客户端计算建立锁的时间,如果建立锁的时间小于超时时间,即建立成功
  5. 如果锁建立失败,那么就依次删除这个锁
  6. 只要别人建立了一把分布式锁,就得不断轮询去尝试获取锁

0 人点赞