什么是RedLock
RedLock是Redis官方提出的基于Redis实现分布式锁的方法。
可以保证
- 安全性 : 互斥访问,即永远只有一个client能拿到锁
- 避免死锁 : 最终的client都能拿到锁,不会出现死锁的情况
- 容错性 : 重要大部分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进行的操作
- 获取当前时间精确到毫秒
- client尝试使用相同的key,value获取所有redis服务的锁,在获取锁的过程中获取时间比锁过期时间要短的多,避免长时间去等待一个已经关闭的redis服务,并试着去获取下一个实例
- client通过获取所有能获取的锁的时间后减去第一步时间,这个时间差要小于TTL时间和至少三个redis实例成功获取锁,才能算真正的获取锁成功
- 如果成功获取锁,那么锁的有效时间是TTL减去第三步的时间差的时间
- 如果获取锁失败,那么将开始解锁所有redis实例,因为已经获取了小于3个锁,必须要释放防止影响其他client获取锁
失败重试
当一个client获取锁失败时,应该稍等一会再重试避免多个client同时申请锁的情况。最好的情况是一个client同时向所有服务发起锁申请
获取锁失败和获取锁的client在完成任务后要及时释放锁
释放锁
释放锁只要向所有实例都发出释放锁的命令,不用考虑能否成功释放锁;
参考文章
版权声明:本文为qq_51088445原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。