← 返回题目列表

分布式锁如何续期?看门狗机制有什么风险?

高频 困难 第 13 / 26 题 更新于 2026/10/01
分布式锁租约看门狗续期
学习 AI 实战项目

简化版

看门狗在持锁任务仍存活时,于租约到期前周期性校验 owner 并延长 TTL,避免正常长任务被误判失锁。它不能消除 GC 暂停、网络分区和旧持有者恢复的问题;续期失败后任务必须停止副作用,下游最好再用 Fencing Token 拒绝迟到写。

详细版

获取锁时生成唯一 owner token,并登记当前进程的续期任务。续期脚本只在 key 的 value 仍属于自己时延长过期时间;业务完成后取消续期并以同样的 owner 校验释放。续期间隔常取租期的约三分之一,并结合调度抖动和失败重试预算校准。

风险包括长时间 STW 超过租期、网络分区下客户端继续工作、调度线程阻塞、业务永不结束导致无限占锁,以及续期与释放竞态。必须监控租约剩余量、续期延迟/失败、长持锁和任务截止时间;对不可安全中断的写入,仅靠看门狗仍不够。

完整版教学

一、为什么需要续期

固定 TTL 太短,正常任务尚未结束锁就被别人获得;TTL 太长,进程宕机后资源长期不可用。看门狗把“故障回收上限”与“正常任务实际耗时”部分解耦:只要 owner 活跃且能通信就续期,失联后由 TTL 回收。

易错点:续期提高的是长任务可用性,不会把租约变成绝对所有权。

二、标准生命周期

acquire(owner=A, ttl=30s)
  -> every 10s: compare owner=A and extend to 30s
  -> business completes
  -> cancel watchdog
  -> compare owner=A and delete

比较与续期必须原子执行,否则读取到 A 后可能被删除重建为 B,再被 A 的续期错误延长。Redis 常用 Lua,具备事务 API 的存储用条件更新。

三、参数怎样计算

租期至少覆盖调度抖动、一次续期 RTT 和允许的重试窗口。若 TTL=30 秒、间隔=10 秒,正常有约 20 秒余量;一次 25 秒 STW 仍可能让锁过期。间隔过密增加锁服务负载,过疏则容错余量小。

参数过小风险过大风险
TTL正常任务失锁故障回收慢
续期间隔服务压力来不及重试
最大持锁时长误杀长任务永久占用
重试次数偶发抖动失锁不确定期延长

四、GC 与网络分区的安全边界

客户端暂停 40 秒,30 秒租约已过期,新客户端 B 获锁;A 恢复时本地线程仍以为业务未完成。此时即使续期请求失败,A 已发出的数据库请求也可能在路上。任务要在关键步骤检查租约状态,下游用更大 fencing token 才能可靠拒绝 A 的迟到写。

A token=7 --pause--> lease expires
B token=8 ----------> write accepted
A resumes token=7 --> write rejected

五、续期与释放的竞态

业务线程结束并释放的同时,调度线程可能正准备续期。正确顺序是标记本地完成、取消后续任务,再通过 owner 条件删除;即使在途续期先到,也只能延长自己的锁,随后条件删除仍安全。不能执行无条件 DEL 或 EXPIRE。

若业务抛异常,finally 只负责尝试释放;释放超时结果未知时,不能盲目删除,应等待 TTL 或查询 owner。

六、防止无限续期与观测

任务逻辑卡死但进程健康时,看门狗会一直续期。应设置业务 deadline 和最大持锁时长,超过后停止续期、标记任务异常并触发人工或补偿。长作业更适合拆分为带 checkpoint 的小步骤,而非持锁数小时。

监控续期成功率、耗时、剩余 TTL、连续失败数、持锁 P99、超过 deadline 数和锁服务负载,并让续期线程池与业务线程池隔离。

七、常见误区与追问

  • 误区:有看门狗就不会锁过期。 长暂停或网络分区仍会超过租约。
  • 误区:续期时直接刷新 TTL 即可。 必须原子校验 owner。
  • 误区:任务还活着就应无限续期。 逻辑卡死会永久占锁。
  • 误区:续期失败后继续写没关系。 此时可能已有新持有者。
  • 追问:为什么常取 TTL 的三分之一续期? 为抖动和多次重试保留余量,但仍需实测。
  • 追问:释放和续期并发怎么办? 两者都做 owner 条件操作,并先取消本地调度。
  • 追问:怎样保护不可中断写? 使用资源侧 fencing 或原子条件版本,而非只依赖续期。

八、加强记忆

看门狗是“带 owner 校验的周期续租”:它平衡短 TTL 与长任务,却不能对抗超出租期的暂停。设计要同时具备原子续期、安全释放、最大执行时间和失锁停止机制;真正涉及数据安全时,再由下游 fencing 把旧持有者挡住。