跳转至

Redis 分布式锁主从架构锁失效问题

一、问题

Redis 主从异步复制:

客户端 A → 主节点:加锁成功
主节点还没把锁同步到从节点
主节点挂了
从节点提升为新主
客户端 B → 新主节点:加锁成功

两个客户端同时持有锁。

二、Redis 的解决方案:RedLock

思路

向 N 个独立的 Redis 节点(不是主从)加锁,多数成功才算成功。

流程

  1. 客户端获取当前时间。
  2. 依次向 5 个独立 Redis 节点加同一个锁。
  3. 半数以上(≥3)成功,且总耗时小于锁有效期,才算成功。
  4. 失败了向所有节点发释放锁。

三、RedLock 的争议

Martin Kleppmann 认为 RedLock 不安全: - GC 暂停导致客户端持锁时间超期。 - 时钟漂移。 - 网络分区。

Redis 作者反驳:锁有有效期,GC 暂停期间锁自动释放。

四、生产实践

1. 对正确性要求高

不用 Redis 锁,用 Zookeeper 或 etcd(CP)。

2. 对性能要求高,能容忍小概率失效

用 Redis 锁 + RedLock。

3. 看门狗(Watchdog)

Redisson 的看门狗自动续期:

RLock lock = redisson.getLock("lock");
lock.lock();   // 默认 30s,看门狗每 10s 续期

五、对比

Redis 锁 Zookeeper 锁 etcd 锁
一致性 AP(可能失效) CP CP
性能
故障 主从切换可能丢锁 不丢锁 不丢锁

六、总结

Redis 主从锁不是绝对安全。业务要能容忍"小概率同时持有",或者用 CP 系统。

不要迷信 RedLock

RedLock 解决了主从异步复制问题,但解决不了 GC 暂停和网络问题。关键业务用 ZK/etcd。