1. 核心概念

Redlock(Redis Distributed Lock) 是 Redis 作者 Antirez 提出的一种基于 Redis 实现的分布式锁算法。

它的核心目的是为了解决 单节点 Redis 分布式锁在主从故障切换时可能丢失锁 的问题。在标准的单实例 Redis 锁中,如果主节点崩溃,而锁数据还没来得及同步到从节点,从节点升级为主节点后,锁就会丢失,导致多个客户端同时持有锁。Redlock 通过在多个独立的 Redis 实例上同时申请锁来提高容错性。

2. 原理与关键点

Redlock 算法假设我们有 N 个(通常是 5 个)完全独立的 Redis master 节点,它们之间没有任何主从关系。

2.1 加锁步骤

  1. 获取当前时间:记录开始尝试获取锁的时间戳 $T_1$。
  2. 依次申请锁:客户端按顺序向这 N 个 Redis 实例请求加锁。
    • 使用相同的 Key 和 Value(随机值,用于解锁校验)。
    • 设置一个较小的网络超时时间(例如 5-50ms),防止在挂掉的节点上阻塞过久。
  3. 计算耗时:当客户端从大多数($N/2 + 1$,例如 5 个中的 3 个)节点成功获取锁后,计算整个过程的耗时 $T_{elapsed} = T_{now} - T_1$。
  4. 验证成功:如果 成功获取锁的节点数 $\ge N/2 + 1$$T_{elapsed} < T_{validity}$(锁的有效时间),则认为加锁成功。
  5. 计算实际有效时间:锁的实际有效时间 = 初始有效时间 - $T_{elapsed}$ - 时钟漂移。

2.2 失败处理

如果获取锁失败(成功节点数不足 或 耗时过长),客户端必须在 所有 节点上执行解锁操作(即使是那些它认为没有加锁成功的节点),以防止残留数据。

3. 考量与争议

3.1 性能与可靠性

  • 容错性:允许 $N/2$ 个节点宕机,锁依然可用。
  • 性能:比单节点 Redis 锁慢,因为需要跨多个节点通信。

3.2 争议(Martin Kleppmann vs Antirez)

分布式系统专家 Martin Kleppmann 曾质疑 Redlock 的安全性,主要基于以下几点:

  • 时钟依赖:Redlock 强依赖服务器时钟。如果某个节点时钟发生跳跃(NTP 同步),可能导致锁提前过期。
  • NPC 问题:Network Delay(网络延迟)、Process Pause(进程暂停/GC)、Clock Drift(时钟漂移)都可能破坏 Redlock 的安全性。

结论:Redlock 适用于对可靠性要求较高、但非绝对严格(允许极低概率的重复锁定)的场景。如果需要绝对的数据一致性(如金融账务),建议使用 ZooKeeperEtcd(基于 CP 模型)。

4. 总结

Redlock 是 Redis 官方推荐的分布式锁高可用方案,通过 多节点投票 机制解决了单点故障导致的锁丢失问题。

面试回答示例:

“Redlock 是 Redis 作者提出的基于多节点 Redis 的分布式锁算法,旨在解决主从切换导致的锁丢失问题。 它的原理是客户端尝试在 N 个独立的 Redis 实例上加锁,只有当在超过半数节点上成功加锁,且总耗时小于锁失效时间时,才视为加锁成功。 虽然它提高了可用性,但因其依赖系统时钟且在极端网络分区下仍有争议,对于强一致性要求的业务,我通常会建议使用 ZooKeeper 或 Etcd。”