Redis中如何实现分布式锁
加解锁、续期都是通过lua脚本实现,具体如下:
- 加锁:使用lua脚本,判断锁是否存在,不存则直接创建锁;锁已存在,则判断锁是不是自己持有,如果是自己持有,计数器+1,否则返回失败 (锁已被其他线程占有)
- 解锁:使用lua脚本,先通过get获取key的value,通过value判断锁是不是自己加的,如果是则del
Redlock红锁
-
部署多个实例,这几个实例彼此独立 不需要有数据同步,客户端尝试在每个实例上加锁,如果大多数实例加锁成功,则表示加锁成功,否则客户端释放所有已经加锁的实例,重新尝试
-
redlock是为了避免主从架构下,一个客户端在主节点加锁成功,但是主节点突然宕机,由于主从延迟导致从节点还没有同步到这个锁信息,此时另一个客户端抢到了新晋升的主节点,这样会导致两个客户端都抢到锁,导致数据不一致
分布式锁可能遇到的问题
- 业务未执行完,锁已到期:开启一个守护线程,定时给锁续期
- 单点故障问题:如果redis单机部署,当实例宕机时整个分布式锁服务将无法工作
- 主从问题:redis的主从复制是异步实现的,当一个客户端在主节点加锁成功,但是主节点突然宕机,由于主从延迟导致从节点还没有同步到这个锁信息,此时另一个客户端抢到了新晋升的主节点,这样会导致两个客户端都抢到锁,导致数据不一致(红锁解决)