Redis分布式锁怎么玩(中)
Redis分布式锁怎么玩(中)
上篇聊到了Redis单节点实现分布式锁的逻辑,较为简单采用set
命令加锁以及Lua脚本解锁就可以实现,但是单机没有高可用的特性,可能因为各种故障宕机这时Redis实现的分布式锁将无法获取锁,所以Redis需要选取集群实现不论是哪种集群如主从、主从-哨兵,切片集群这些都会面临一个问题故障转移,当master节点故障后集群内部通过选举的方式从众多salve节点中获取新的master节点,然后进行主从同步,恰恰就是这时会出现问题,因为主从复制是异步的,锁在主从复制过程中就可能丧失安全性,场景如下
-
客户端1从Redis集群中master节点获取锁并且成功
-
master宕机,这时master的数据还未同步到slave节点
-
从slave节点中选举master节点
-
客户端2向master节点获取锁并且成功
这时客户端1和客户端2获取了相同资源的锁,锁的安全性得不到保证,Redis针对这种场景提出了一种解决方案RedLock红锁。
解决方案—RedLock红锁
红锁官方文档位置https://redis.io/docs/reference/patterns/distributed-locks/,Redis文档指出如果我们需要使用RedLock那么需要部署N个实例节点,注意这N个节点并不是主从关系,也不是任何集群关系,相当于N个独立的实例,官方推荐实例个数N=5
如何实现RedLock
-
客户端获取锁之前先获取当前的时间戳T1。
-
客户端依次向这N个实例加锁,采用
set ex ** nx
命令,每个请求都会设置超时时间,这个超时时间将远小于锁的过期时间,如果某一个实例加锁失败(实例宕机、锁被其它客户端持有、网络超时等等),那么将立即向下一个实例加锁。 -
对所有的实例完成加锁操作后得到时间戳T2,计算加锁成功的个数,如果成功个数大于等于N/2+1,并且T2-T1小于键值的超时时间,这时加锁成功,如果有任意一条不符合则加锁失败。
-
加锁成功,操作共享资源。
-
加锁失败向所有节点释放锁,不论实例有没有加锁成功,释放锁采用Lua脚本完成。
RedLock的注意点
为什么需要给多个实例加锁
保证RedLock的高可用,部分节点宕机依然可以使用。
为什么需要计算加锁这个过程的耗时
因为多个节点需要依次加锁,加锁过程可能遇到网络阻塞、丢包、延迟等情况,即便大多数节点加锁成功,那么有可能最先加锁的实例锁已经过期,那么后续操作将再无其它意义。
为什么给所有节点释放锁
为什么是所有这里一定需要注意,因为加锁这个过程有可能实例加锁成功,但实例将成功结果返回客户端时出现丢包,客户端认为其加锁失败了,所以在解锁时需要给所有的节点解锁,这样才能保证锁的及时释放。
那么RedLock就能解决故障转移的问题了吗,这里看似确实解决了,但是也带来了一个新问题,实例的持久化将影响锁的安全性。
实例持久化对RedLock的影响
假设存在五个实例节点A、B、C、D、E,有如下场景
-
客户端1,依次给实例A、B、C加锁并且成功,实例D、E因为网络问题加锁失败。
-
这时节点C突然宕机,并且锁的键值并没有持久化到磁盘。
-
节点C重启,客户端2连接到实例D、E然后给C、D、E加锁成功。
这时客户端1和客户端2就拥有了同一把锁,锁又不安全了。
无论持久化是AOF还是RDB,都是存在数据丢失的风险,这个无法避免,为了应对这一问题,Redis作者antirez又提出了新概念延迟重启,也就是说在一个节点崩溃后,先不立即重启它,而是等待一段时间,这个时间间隔应该是大于键值的过期时间,这样就能避免实例宕机给RedLock的影响。
其它疑问
RedLock确实能够做到避免故障转移带来的问题,但有一些之前单实例做分布式锁中提到的问题如下
-
客户端获取锁后,执行业务时间过长导致实例上的锁过期,这时RedLock是否能处理呢?答案是否定的。
-
客户端加锁成功后,可能剩余的有效时间太短了无法完成业务,那么是否需要选择释放锁呢,这也是一个难题。
资料参考
http://zhangtielei.com/posts/blog-redlock-reasoning.html
https://mp.weixin.qq.com/s/s8xjm1ZCKIoTGT3DCVA4aw
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~