RedLock的存在意义
上篇提到了安全性,那么试想这样一个主从集群模式下的场景:
- 客户端A在master节点获取到了锁
- master故障,通过leader选举产生了新的master,由于数据还没同步,客户端B拿到了锁
标题RedLock 加锁原理
1.获取当前时间,设置超时时间TTL(需要大于业务执行时间+获取锁的时间)
2.依次从每个节点获取锁,需要设置网络连接的超时时间(防止客户端阻塞,这个设置要小于TTL)
3.客户端获取到了所有能获取的锁,可以计算获取锁消耗的时间(要达到半数以上的节点才算成功)
4.锁的有效时间等于TTL-获取锁消耗的时间
5.如果获取锁失败则应该为所有节点释放锁
6.失败(未达半数||超时)后进行随机时间重试,防止并发重试
崩溃恢复:
目前单个节点的故障已经不足为惧,但是如果全部节点重启,安全性就与持久配置有关——
- 如果没有开启持久化,a获取锁后全部实例重启,b就可以获取锁,这样导致锁不具有排他性,a还以为自己占有锁
- 例如aof刷磁盘的时间设置为每秒,那么全部重启后理论上就会丢失那一秒的数据,导致上面的问题。
- 如果把刷盘的时间设置为always,可以基本保证安全性,但是性能会大幅下降。
延时重启:为了避免上面提到的互斥性问题,redlock的作者提出了延迟重启,即延时TTL的时间再进行重启,保证上一次的锁全部过期,避免锁冲突。