← 返回题目列表

Redlock 为什么有争议?项目里该怎么取舍?

高频 困难 第 16 / 26 题 更新于 2026/10/01
RedlockRedis分布式锁Fencing Token
学习 AI 实战项目

简化版

Redlock 在多个彼此独立的 Redis 主节点上竞争多数锁,并要求总耗时小于租期;争议在于它仍依赖租约、时钟假设和客户端及时停止,无法单靠多数 Redis 阻止暂停后的旧持有者操作资源。项目选型应按错误后果决定:低风险防重复可用,强一致写优先使用共识协调与资源侧 Fencing Token。

详细版

典型算法向 N 个独立 Redis 节点用相同 token 获取锁,在超时内拿到多数且剩余有效期为正才算成功;失败时向所有节点安全释放。节点应相互独立,不能是同一异步复制主从组,否则共同故障会破坏多数假设。

即使算法按设计运行,客户端仍可能在租约过期后因 GC、网络延迟继续执行;系统时钟跳变和长暂停也会侵蚀有效期判断。Redlock 适用于允许偶发重复、业务还有幂等兜底的场景;资金、唯一主写等安全性要求高的场景,应使用线性一致协调服务,并让下游验证单调代次。

完整版教学

一、Redlock 想解决什么问题

单 Redis 锁在节点故障时不可用;若用异步主从故障转移,锁写入未复制就切主,新主可能再次授锁。Redlock 不依赖一个主从组,而是同时使用多个独立主节点,希望通过多数派降低单节点丢锁的风险。

易错点:多数派提高的是锁记录在节点故障下的可靠性,不会自动约束已经拿到锁的客户端进程。

二、算法步骤

以 5 个节点为例,客户端记录开始时间,按经典流程依次用同一 token 和 TTL 尝试 SET NX PX,并为每个节点设置远小于 TTL 的连接与命令超时,避免故障节点拖完租期。至少 3 个成功,且总耗时小于 TTL,才认为获得锁;有效时间还要扣除获取耗时与时钟漂移余量。工程实现可用连接复用降低耗时,但不能改变多数、超时和有效期判定。

N = 5, quorum = 3, TTL = 10s
R1 OK, R2 OK, R3 OK, R4 timeout, R5 fail
elapsed = 1.2s
validity ≈ 10s - 1.2s - drift_margin

失败或业务结束时,都用 owner token 向全部节点执行条件删除。

三、节点独立性为何关键

五个“节点”若其实是同一机房、共享电源或同一主节点的异步副本,就不是五个独立故障域。多数判断假设故障相对独立;公共网络、宿主机暂停或统一运维误操作会让相关故障同时发生。

部署是否满足独立主假设风险
5 个独立主较接近成本与跨域延迟
1 主 4 从否复制与主从同命运
同宿主 5 实例否宿主共同故障
多 AZ 独立节点较好网络分区与 RTT

四、争议的核心不是“会不会过期”

客户端 A 获得多数锁后暂停超过 TTL,B 随后也合法获得多数;A 恢复后仍可能写数据库。Redlock 的锁记录已正确过期,但资源同时看到两个执行者。任何基于租约的锁都有这个边界,除非客户端能被可靠停止,或资源侧拒绝旧代次。

单调 Fencing Token 可以让数据库识别 B 比 A 新;随机 Redlock token 只能用于安全解锁,不能比较代次。这也是强一致场景常把共识日志索引作为 fencing 的原因。

五、时间假设与有效期

Redlock 使用本地经过时间判断剩余租期,要求节点时钟不会发生剧烈跳变,客户端执行和网络延迟有合理上界。应使用单调时钟测耗时,但 Redis TTL 本身仍受服务器时间实现与运维环境影响。长 GC 或虚拟机暂停无法靠平均 RTT 预算消除。

假设 TTL 10 秒、获取耗时 4 秒、漂移余量 0.2 秒,真正可用窗口只约 5.8 秒;业务若需 8 秒,获取多数也不应开始执行。

六、项目如何取舍

缓存重建、防止重复定时任务等允许偶发重复且业务幂等的场景,可用单 Redis 锁或 Redlock 提升可用性,前提是明确失败后果。库存、余额和唯一 leader 写入若错误会破坏数据,应优先采用 ZooKeeper/etcd 等共识协调,并在最终资源实施版本或 fencing 校验。

评审要记录安全不变量、故障模型、最大暂停、部署独立性、租期依据和演练结果,而不是只问“Redlock 官方是否推荐”。

七、常见误区与追问

  • 误区:拿到多数 Redis 就等于线性一致锁。 多数成功本身不能阻止旧客户端迟到执行。
  • 误区:五个主从副本就是五个独立节点。 复制关系和共同故障域不满足假设。
  • 误区:随机 token 可以充当 Fencing Token。 随机值不能表达授锁先后。
  • 误区:把 TTL 调大就没有争议。 只能降低概率,同时拉长故障回收。
  • 追问:Redlock 能不能用? 取决于错误后果、幂等兜底和故障假设,不能绝对回答。
  • 追问:为什么共识服务仍需 fencing? 客户端获得租约后也可能暂停,最终资源仍需拒绝旧代次。
  • 追问:如何验证独立性? 检查电源、宿主、网络、地域和运维变更等共同故障域。

八、加强记忆

Redlock 的回答主线是“独立多主—多数获取—扣除耗时—条件释放”,再指出它只改善锁记录的容错,不能取消租约与暂停的物理边界。低风险协调看可用性与成本,高风险写入看安全不变量,并用共识授予、Fencing Token 和业务幂等形成最终闭环。