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分布式锁

对比:

特性RedlockZooKeeper
一致性模型最终一致强一致
实现复杂度
性能很低
可用性
故障恢复容易复杂
成本

选择建议:

使用 Redlock:
- 已有 Redis 基础设施
- 性能要求相对较高
- 可容忍最终一致

使用 ZooKeeper:
- 强一致性要求
- 需要 watcher 机制
- 复杂的协调场景

思考题

  1. Redlock 算法在”网络分区”时如何保证正确性?

  2. 如何实现 Redlock 的”锁超时自动续期”?

  3. Redlock 算法是否真的安全?有哪些已知的攻击方式?

💡 提示:这些问题没有标准答案,建议结合实际情况深入思考。