前言
主要记录下,Redisson中RedLock加锁算法的实现
Redisson分布式锁的缺点
由于Redisson的加锁方式,本质上时是判断某个Redis节点(主节点)是否具有某个key,且Redis集群间会发生异步的主从复制行为,可能会出现重复加锁的问题
在极端情况下,
客户端A加锁成功后,master节点数据会异步复制到slave节点,此时当前持有Redis锁的master节点宕机,slave节点被提升为新的master节点;
客户端B再次加锁,在新的master节点上加锁也也会成功,这个时候客户端B也会认为加锁成功,出现两个节点同时持有一把锁的问题;
此时就会产生脏数据的问题
RedLock算法
场景是假设有一个redis cluster,有3个redis master实例
然后执行如下步骤获取一把分布式锁:
1)获取当前时间戳,单位是毫秒
2)跟上面类似,轮流尝试在每个master节点上创建锁,过期时间较短,一般就几十毫秒,在每个节点上创建锁的过程中,需要加一个超时时间,一般来说比如几十毫秒如果没有获取到锁就超时了,标识为获取锁失败
3)尝试在大多数节点上建立一个锁,比如3个节点就要求是2个节点(n / 2 +1)
4)客户端计算建立好锁的时间,如果建立锁的时间小于超时时间,就算建立成功了
5)要是锁建立失败了,那么就依次删除已经创建的锁
6)只要别人创建了一把分布式锁,你就得不断轮询去尝试获取锁
注意:普通的redis分布式锁,其实是在redis集群中根据hash算法选择一台redis实例创建一个锁就可以了
RedLock算法思想,不能只在一个redis实例上创建锁,应该是在多个redis实例上创建锁,n / 2 + 1,必须在大多数redis节点上都成功创建锁,才能算这个整体的RedLock加锁成功,避免说仅仅在一个redis实例上加锁
RedLock缺点:
1.红锁是很少使用的。这是因为使用了红锁后会影响高并发环境下的性能,使得程序的体验更差。
2.使用红锁时,需要提供多套Redis的主从部署架构,同时,这多套Redis主从架构中的Master节点必须都是独立的,相互之间没有任何数据交互。
3.使用红锁后,当加锁成功的RLock个数不超过总数的一半时,会返回加锁失败,即使在业务层面任务加锁成功了,但是红锁也会返回加锁失败的结果。
备注:实际场景中,一般都是要保证Redis集群的可靠性,而不使用RedLock算法实现的分布式锁