什么是RedLock

RedLock是Redis官方提出的基于Redis实现分布式锁的方法。

可以保证

  1. 安全性 : 互斥访问,即永远只有一个client能拿到锁
  2. 避免死锁 : 最终的client都能拿到锁,不会出现死锁的情况
  3. 容错性 : 重要大部分redis节点存活就可以正常提供服务

单节点上实现分布式锁

SET key_name my_random_value NX PX 30000  

NX 表示if not exist 就设置并返回True,否则不设置并返回False (仅当key不存在时设置) PX 表示过期时间用毫秒级, 30000 表示这些毫秒时间后此key过期

删除自己设置的锁

删除原因 : 保证服务器资源的高利用效率,不用等到锁自动过期后才删除

删除方法 : 最好使用Lua脚本删除(redis保证执行此脚本时不执行其他操作,保证操作的原子性),代码如下;逻辑是 先获取key,如果存在并且值是自己设置的就删除此key;否则就跳过;

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

实现RedLock算法

算法流程,开启五个节点,为了索取锁,client进行的操作

  1. 获取当前时间精确到毫秒
  2. client尝试使用相同的key,value获取所有redis服务的锁,在获取锁的过程中获取时间比锁过期时间要短的多,避免长时间去等待一个已经关闭的redis服务,并试着去获取下一个实例
  3. client通过获取所有能获取的锁的时间后减去第一步时间,这个时间差要小于TTL时间和至少三个redis实例成功获取锁,才能算真正的获取锁成功
  4. 如果成功获取锁,那么锁的有效时间是TTL减去第三步的时间差的时间
  5. 如果获取锁失败,那么将开始解锁所有redis实例,因为已经获取了小于3个锁,必须要释放防止影响其他client获取锁

image-20220220114953569

失败重试

当一个client获取锁失败时,应该稍等一会再重试避免多个client同时申请锁的情况。最好的情况是一个client同时向所有服务发起锁申请

获取锁失败和获取锁的client在完成任务后要及时释放锁

释放锁

释放锁只要向所有实例都发出释放锁的命令,不用考虑能否成功释放锁;

参考文章

Redlock(redis分布式锁)原理分析 - RGC - 博客园 (cnblogs.com)

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐