连载中 5/20

RedLock 之争:Martin 与 antirez 的隔空交锋

2026-06-27 · 4347 阅读 · 0 评论 · 0 赞

RedLock 是什么药方

前三篇攒出的 Redisson 锁有个前提没挑明:锁数据只存在一台 Redis 上。单点不可用时锁服务全停(可用性问题),主从复制时锁记录可能来不及同步到从库就随主库一起消失(安全性问题,第 7 篇展开)。Redis 之父 antirez 给出的处方是 RedLock(红锁):不搞主从、不用集群,摆 N 个(推荐 5 个)完全独立、互不通信的 Redis 主节点,客户端依次向每个节点加锁——

1. 记录开始时间 T0,依次向 5 个节点 SET NX PX(同一个随机 value)
2. 收集成功数,并记录结束时间 T1
3. 判定拿到锁 = 成功节点数 >= 3(多数派)
   且 T1 - T0 < 锁有效期(别把剩余时间全耗在加锁路上)
4. 真实有效期 = 原始 TTL - 加锁耗时
5. 任何一步不满足 → 向全部 5 个节点发解锁请求(哪怕没加成功)

思路是多数派仲裁:锁的状态不再取决于一台机器的生死,而取决于过半节点的共识——挂 1 台、2 台不影响判定,也不存在「锁记录没同步到从库」的问题,因为根本没有从库。2016 年之前,这被普遍视为 Redis 分布式锁的「正确姿势」,直到有人写了篇博客。

Martin 的两板斧

Martin Kleppmann——《DDIA》的作者,分布式系统的布道者——发文《How to do distributed locking》,对 RedLock 的安全性提出了两个否定。第一板斧是GC 停顿:客户端 1 拿到 RedLock,随即发生长停顿(GC、虚拟机挂起、缺页),停顿期间锁过期,RedLock 的多数派到期自动放锁,客户端 2 顺利拿到锁开始写;客户端 1 复活后完全不知道锁已易主,继续往下游写——两个持有者同时进临界区,RedLock 的「安全」在这个场景下不成立。注意,这不是 RedLock 的实现 bug,而是「锁的过期靠时间、进程不知道自己被冻结过」这一类时间型锁的共同软肋

第二板斧是时钟跳变:RedLock 判定「锁未过期」依赖各节点的本地时钟。某节点管理员手动改时间、NTP 校准大幅回拨,锁的 TTL 被瞬间清零——多数派里多一台时钟异常,判定就失真。Martin 的结论很刻薄也很清晰:RedLock 建立在「时间可信」的假设上,而分布式系统恰恰不能假设时间可信

antirez 的反击与论战的真正遗产

antirez 逐条回击:GC 停顿场景,RedLock 客户端持有随机 token,下游可以拒绝「token 已过期」的写入(Martin 自己提的 fencing token,antirez 认为可用);时钟跳变,RedLock 可以用「相对时间计数」缓解(TTL 用单调时钟推进),实际工程里 NTP 配置成步进而非跳变。Martin 则回敬:fencing token 要下游存储配合校验,配得上这套配置的存储(多数数据库)自己就有并发控制,RedLock 反而多余了。论战没有判出胜负,却给所有用锁的人沉淀了两条真理。

真理一:先分清锁的用途——效率还是正确性。效率锁:两个人同时干重复的活浪费资源,锁只是避免浪费(定时任务防重复跑、缓存防击穿重建),偶尔双跑一次无伤大雅;正确性锁:双跑就是事故(扣款、扣库存),绝不容忍同时进入临界区。真理二:正确性场景锁本身靠不住,必须给下游发「单调递增的令牌」(fencing token)让写入可仲裁——这块留给第 16 篇细讲。

方案安全性复杂度适用
单实例 Redisson主从切换可能丢锁(小概率)低,一个 Redis 就够效率锁,配幂等兜底可覆盖大多数业务
RedLock优于单实例,GC/时钟场景仍有缺口高,5 个独立主节点运维成本大容忍极小概率风险又要比单实例稳的场景
fencing token 方案可做到严格安全需要下游存储配合校验正确性锁,钱和库存
ZooKeeper / etcd一致性协议背书,会话机制天然防死锁需独立维护协调服务正确性锁的现成答案(第 8 篇起)

老王听完论战的转述,总结得比我狠:「就是说 RedLock 花五台机器的钱,买到『比单实例强点,但还是不保证不出事』?」——大抵如此。多数团队的最优解其实是:单实例 Redisson 当效率锁用,配上幂等(分布式事务系列第 10 篇)兜底;真正碰不得的业务,交给后面几篇的 ZooKeeper 和 etcd。下一篇插播一个性能话题:一百个线程同时抢一把锁会发生什么——等待与唤醒的艺术。

503

10 年全栈工程师 · 503咖啡馆主理人

#分布式锁#RedLock#Martin Kleppmann#antirez#fencing token

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞