这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
Redlock 算法
单点故障问题
在上一节,我们实现了基于单 Redis 实例的分布式锁。
但在生产环境中,我遇到了一个严重问题:
故障场景:
T0: 正常运行,系统使用 Redis-1 作为锁服务
T1: Redis-1 所在服务器故障(宕机/网络断开)
T2: 所有应用服务器无法获取锁
T3: 系统不可用!
影响:
- 点赞功能全部停止
- 用户无法操作
- 业务严重受损
单点故障(SPOF)是分布式系统的大忌。
Redlock 算法原理
Redlock(Redis Distributed Lock) 是 Redis 作者 Antirez 提出的分布式锁算法。
核心思想:
- 使用多个独立的 Redis 实例(通常 5 个)
- 同时在这些实例上获取锁
- 只有在大多数实例上获取成功才算真正获取到锁
- 降低单点故障的影响
示意图:
单实例锁:
应用服务器 → Redis-1 → 锁
↑____________↑
单点故障风险
Redlock:
应用服务器 → Redis-1 ━━
→ Redis-2 ━━┳━→ 获取大多数锁(3/5)
→ Redis-3 ━━┃
→ Redis-4 ━━┃
→ Redis-5 ━━┛
算法流程:
1. 获取当前时间戳 T1
2. 按顺序依次在 N 个 Redis 实例上获取锁
- 使用相同的 key 和随机 value
- 设置相同的过期时间
- 每个实例获取锁的超时时间远小于锁的过期时间
3. 计算获取锁消耗的时间:T2 - T1
4. 判断是否成功:
- 在大多数实例上获取成功(N/2 + 1)
- 且获取锁的时间小于锁的过期时间
5. 如果成功,持有锁
如果失败,释放所有已获取的锁
6. 释放锁:
- 在所有实例上释放锁
- 只有锁的 value 匹配才释放
完整方案
Redlock 类
使用示例
上下文管理器
自动续期
故障场景测试
场景 1:单个实例故障
场景 2:网络分区
场景 3:时钟跳变
Redlock vs 单实例锁
对比
| 特性 | 单实例锁 | Redlock |
|---|---|---|
| 可用性 | 低(单点故障) | 高(多数派可用) |
| 一致性 | 高 | 高 |
| 性能 | 高(1 次网络往返) | 低(5 次网络往返) |
| 复杂度 | 低 | 高 |
| 成本 | 低(1 个 Redis) | 高(5 个 Redis) |
性能测试
适用场景
使用单实例锁:
- 开发/测试环境
- 可容忍短暂不可用
- 成本敏感
- 性能要求高
使用 Redlock:
- 生产环境
- 高可用要求
- 强一致性要求
- 成本不敏感
课后练习
练习 1
Redlock 算法为什么需要”大多数”实例成功?
参考答案(3 个标签)
Redlock分布式锁一致性
多数派原则:
为什么需要大多数(N/2 + 1)?
1. 避免脑裂
- 如果只需要少数,可能出现多个客户端同时持有锁
- 示例:5 个实例,2 个即可
- 客户端 A 在实例 1,2 获取锁
- 客户端 B 在实例 3,4 获取锁
- 两个客户端都认为自己持有锁
2. 保证唯一性
- 大多数原则确保只有一个客户端能获取锁
- 最多只能有一个多数派
3. 容错能力
- 5 个实例,容忍 2 个故障
- N 个实例,容忍 (N-1)/2 个故障练习 2
Redlock 算法如何处理”时钟跳变”?
参考答案(3 个标签)
Redlock时钟分布式系统
时钟跳变问题:
问题:
- 不同 Redis 实例时钟可能不同步
- 服务器时钟可能被手动调整
- NTP 同步可能跳变
影响:
- 锁提前过期
- 客户端误认为锁已释放
解决方案:
1. 使用 NTP 同步所有服务器时钟
2. 增加时钟偏差容错
3. 使用更长的 TTL
4. 监控时钟漂移练习 3
Redlock 算法有哪些争议?
参考答案(3 个标签)
Redlock争议分布式锁
主要争议:
1. 时钟依赖
- Redlock 依赖系统时钟
- 时钟跳变可能导致问题
- Martin Kleppmann 的质疑
2. 网络分区
- 网络分区时可能出现脑裂
- 客户端可能长时间阻塞
3. 性能问题
- 需要访问多个实例
- 性能较差
4. 实现复杂
- 容易实现错误
- 难以测试
替代方案:
- ZooKeeper
- etcd
- 数据库练习 4
如何实现 Redlock 的”公平锁”?
参考答案(3 个标签)
Redlock公平锁调度
公平 Redlock 实现:
练习 5
Redlock 和 ZooKeeper 锁有什么区别?
参考答案(3 个标签)
RedlockZooKeeper分布式锁
对比:
| 特性 | Redlock | ZooKeeper |
|---|---|---|
| 一致性模型 | 最终一致 | 强一致 |
| 实现复杂度 | 高 | 中 |
| 性能 | 低 | 很低 |
| 可用性 | 高 | 高 |
| 故障恢复 | 容易 | 复杂 |
| 成本 | 中 | 高 |
选择建议:
使用 Redlock:
- 已有 Redis 基础设施
- 性能要求相对较高
- 可容忍最终一致
使用 ZooKeeper:
- 强一致性要求
- 需要 watcher 机制
- 复杂的协调场景思考题
-
Redlock 算法在”网络分区”时如何保证正确性?
-
如何实现 Redlock 的”锁超时自动续期”?
-
Redlock 算法是否真的安全?有哪些已知的攻击方式?
💡 提示:这些问题没有标准答案,建议结合实际情况深入思考。
