分布式锁;Redlock
文章目录
- 普通单 Redis 锁
- 多节点 Redlock
- Raft
- redis分布式锁宕机被破坏怎么恢复(答红锁觉得效率太低……)
- Zookeeper
普通单 Redis 锁
SET key value NX PX ttl
持锁客户端宕机,锁会在 ttl 过期后自动释放。
但是过期时间太长影响别人获取;太短业务还没处理完也不行。也要避免释放别人锁。
多节点 Redlock
官方解读: https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/
在 N 个独立 Redis 节点上加锁,保证大多数节点(过半)同意加锁才成功。
理论上防止单节点故障导致锁失效。
但是效率低,需要多次网络交互,容易受时钟漂移影响。(多个独立节点,机器的时钟可能不同 而导致问题)
Raft
Raft 是一个分布式共识协议,保证多个节点之间的一致性。
- 锁的状态写入 Raft 集群的日志。
- 只有写入日志且被多数节点确认,锁才算加成功。
- 即使某些节点宕机,只要多数节点存活,锁状态就不会丢失。
redis分布式锁宕机被破坏怎么恢复(答红锁觉得效率太低……)
- 心跳续租:
单节点定时续租 - Redis Stream / 队列 + 唯一标识:
改为从消息队列中取消息执行 - 外部协调服务:
etcd / Zookeeper / Consul 提供分布式一致性锁。
Zookeeper
Zookeeper 是一个分布式协调服务,核心提供 一致性、高可用、顺序性、原子性 的特性。
常用于:分布式锁、配置管理、集群管理、命名服务
ZK 不是高吞吐量服务,锁竞争频繁时可能成为瓶颈
分布式锁:
-
每个客户端在某个目录下创建一个 临时顺序节点。
-
节点的序号天然表示了申请锁的顺序。
-
拿到最小序号的客户端获得锁。
-
当锁释放(客户端删除节点或会话断开)时,其他客户端通过监听前一个节点,继续竞争锁。
操作流程:
假设锁路径是 /locks/my_lock。 (ZK的目录)
- 客户端在 /locks/my_lock 下创建临时顺序节点
/locks/my_lock/lock-000000001
/locks/my_lock/lock-000000002
/locks/my_lock/lock-000000003 - 客户端获取自己节点的序号,并查看是否是最小序号
最小序号 → 获得锁
不是 → 监听比自己小的前一个节点的删除事件(WATCH) - 当前一个节点被删除 → 收到事件 → 再次检查自己是否最小 → 如果是则获得锁
- 客户端完成任务后删除自己的节点,释放锁