.redis redlock
什么是RedLock?
要实现RedLock,需要至少5个实例(官方推荐),且每个实例都是master,不需要从库和哨兵。
实现流程
1、客户端先获取当前时间戳T1
2、客户端依次向5个master实例发起加锁命令,且每个请求都会设置超时时间(毫秒级,注意:不是锁的超时时间),如果某一个master实例由于网络等原因导致加锁失败,则立即想下一个master实例申请加锁。
3、当客户端加锁成功的请求大于等于3个时,且再次获取当前时间戳T2,
当时间戳T2 - 时间戳T1 < 锁的过期时间。则客户端加锁成功,否则失败。
4、加锁成功,开始操作公共资源,进行后续业务操作
5、加锁失败,向所有redis节点发送锁释放命令
即当客户端在大多数redis实例上申请加锁成功后,且加锁总耗时小于锁过期时间,则认为加锁成功。
释放锁需要向全部节点发送锁释放命令。
第3步为啥要计算申请锁前后的总耗时与锁释放时间进行对比呢?
因为如果申请锁的总耗时已经超过了锁释放时间,那么可能前面申请redis的锁已经被释放掉了,保证不了大于等于3个实例都有锁存在了,锁也就没有意义了
这样的话分布式锁就真的没问题了嘛?
1、得5个redis实例,成本大大增加
2、可以通过上面的流程感受到,这个RedLock锁太重了
3、主从切换这种场景绝大多数的时候不会碰到,偶尔碰到的话,保证最终的兜底操作我觉得也没啥问题。
4、分布式系统中的NPC问题
- 按顺序向5个master节点请求加锁
- 根据设置的超时时间来判断,是不是要跳过该master节点。
- 如果大于等于三个节点加锁成功,并且使用的时间小于锁的有效期,即可认定加锁成功啦。
- 如果获取锁失败,解锁!