前言
用 Redis 实现分布式锁,是我们常见的实现分布式锁的一种方式
下面是 redis 实现 分布式锁的四种方式,每种方式都有一定的问题,直到最后的 zookeeper
先透露一下:
Redission 解决了 set ex nx 无法自动续期的问题
RedLock 解决了 Redission 和 set ex nx 的单点故障问题
Zookeeper 解决了 RedLock 实现复杂的问题
set ex nx
在 Redis 中实现分布式锁的常见方法是通过 set ex nx 命令 + lua 脚本组合使用。确保多个客户端不会获得同一个锁的同时,也保证了安全解锁和意外情况下锁的自动释放
ex:设置过期时间,单位是 s nx:仅当键不存在时才设置
加锁:SET lock_key uniqueValue EX expire_time NX
解锁:使用 lua 脚本,先通过 get 获取 key 的 value 判断锁是否是自己加的,如果是则 del
之所以要有 uniqueValue 是为了防止被别的客户端给释放了
Redission
set ex nx 缺点就是锁的续期问题,只能设置一个固定时间,如果未完成逻辑锁就过期了,数据就可能产生不一致
所以需要一个看门狗机制,redission 就是一个好用的方式
看门狗机制
业界出了一个看门狗机制来防止这种情况的产生。
理论很简单,在抢到锁之后,后台会有一个任务,定时向 redis 进行锁的续期。比如锁的过期时间是 30s,可以每过三分之一时长(30/3)10s 后就去 redis 重新设置过期时间为 30s。
在锁被释放的时候,就移除这个定时任务。
redission
redission是一个类库,封装了很多redis操作,便于我们使用。
其实现的分布式锁就引入了看门狗机制,具体原理和上面所述的一致
RedLock
set ex nx 和 redisson 有什么缺点:单点故障
单点故障问题
单台 Redis 实现分布式锁存在单点故障问题,如果采用主从读写分离架构,如果一个客户端在主节点上锁成功,但是主节点突然宕机,由于主从延迟导致从节点还未同步到这个锁,此时可能有另一个客户端抢到新晋升的主节点上的锁,此时会导致两个客户端抢到锁,产生了数据不一致。
基于这个情况,Redis 推出了 Redlock。
Zookeeper
zookeeper 暂时还没有学,先搁置一下吧,欢迎评论区交流