备案站点的分布式锁与选主实践
作者:备案源头内容团队内容审核:备案源头内容团队更新于 2026年9月16日
扩到第二个实例的那天,很多假设就失效了
单实例时代,「同一时刻只有一个人在处理这笔数据」是天然成立的。扩容到多实例后,这个假设立刻消失:两个实例同时触发同一个定时任务、同时扣减同一笔库存、同时发出同一条通知。分布式锁就是用来找回这个假设的——但它给回来的东西,比很多人以为的要弱。
关键要点
- 分布式锁是降低冲突的手段,不是正确性的最终保障;正确性要靠幂等或唯一约束兜底。
- 锁必须有租约(自动过期),否则持有者宕机就是永久死锁;而一旦有了租约,就必然存在「自以为还持有、实际已过期」的窗口。
- 进程停顿、网络分区、时钟漂移都会放大这个窗口,fencing token 是唯一能在存储侧挡住僵尸持有者的通用手段。
- 需要严格互斥或选主时,用支持共识与会话的组件,不要在单点存储上自己造。
三种实现的正确性差异
| 实现方式 | 正确性强度 | 复杂度 | 适用场景 |
|---|---|---|---|
| 数据库唯一键或行锁 | 依赖事务,较强 | 低 | 低频任务、量不大的互斥 |
| 缓存的原子写入(带过期) | 尽力而为 | 低 | 高频、可容忍偶发重复 |
| 共识组件的会话与租约 | 强,带自动失效 | 高 | 选主、严格互斥 |
有一点必须说清楚:基于异步主从复制的缓存做锁,在主节点故障切换时锁可能「复活」——加锁写入还没复制到从节点,切换后新主上这把锁不存在,于是第二个实例也能拿到。这不是配置没调好,而是复制模型决定的,属于该方案的固有代价。能接受这个代价(有幂等兜底)再用,别把它当成严格互斥。缓存本身的运维见 缓存与 Redis 运维,数据库侧的一致性与切换见 数据库运维与高可用。
租约与续期:那个危险窗口
锁一定要设过期时间,否则持有者进程被杀、机器宕机,锁就永远留在那里,业务全面停摆。但设了过期时间就带来新问题:任务还没做完,锁先到期了,另一个实例合法地拿到锁,两个实例开始并行执行——而第一个实例对此一无所知。
常见的补救是「看门狗」后台续期。它有效,但挡不住下面这些情况:
- 进程发生长时间停顿(垃圾回收、磁盘或交换分区抖动),续期线程也一起被冻住。
- 到锁服务的网络短暂中断,续期请求失败。
- 机器时钟被大幅纠正,导致对剩余租期的判断出错,见 时钟同步与时区治理。
所以工程上的三条经验是:过期时间要显著大于任务的 P99 耗时;长任务拆成小步、每步独立加锁;执行关键写入之前重新确认自己仍然持有锁。
Fencing token:挡住僵尸持有者
既然「自以为持锁」无法彻底避免,就只能在写入的那一侧做防护。做法是每次获得锁时附带一个单调递增的序号,带着它去写下游;下游记录见过的最大序号,拒绝比它小的写入。这样即使停顿恢复后的旧持有者继续写,也会被直接拒绝。
没有条件实现序号防护时,就必须退回到幂等与唯一约束:用业务唯一键做去重表、用状态机限制合法流转、用条件更新并检查受影响行数。幂等键的做法见 超时设置与重试策略 与 消息队列与异步任务运维。
选主与脑裂
选主比互斥更严格:它要求任意时刻最多只有一个主,且切换过程可控。
- 脑裂指网络分区后两侧各自选出主,双主同时写入,恢复后数据冲突几乎无法自动合并。
- 防护手段有二:多数派原则(只有拿到超过半数投票的一方才能成为主,少数派自动放弃),以及隔离(把旧主从写入路径上摘掉,或用序号在存储侧拒绝旧主的写入)。
- 数据库主从的自动切换同理,最危险的不是切换失败,而是切换后旧主仍能接受写入。切换流程必须演练,方法见 故障演练与预案验证。
锁粒度与等待策略
- 锁业务键而不是全局锁:按订单号、用户 ID 加锁,并行度才保得住。一把全局锁会把整个并行系统退化成串行,吞吐直接被锁死,容量影响见 性能优化与压测。
- 不要无限等待:定时任务场景拿不到锁就跳过本轮(因为下一轮还会来),在线请求场景应快速失败并退避重试。
- 持锁期间不要做远程调用:一旦调用第三方接口,锁的持有时长就被外部依赖的响应时间绑架了,见 第三方服务依赖治理。
- 锁要有可观测性:等待时长、持有时长、获取失败率、续期失败次数都该有指标,见 可观测性建设 与 备案网站监控告警体系。
有些场景其实不需要锁
| 场景 | 更简单的做法 |
|---|---|
| 防止重复插入 | 唯一索引,冲突即失败 |
| 同一业务键顺序处理 | 按键路由到同一分区串行消费,见 消息队列与异步任务运维 |
| 并发更新同一行 | 版本号乐观并发,冲突重试 |
| 扣减库存 | 带条件的原子更新,按受影响行数判断成败 |
| 多实例定时任务 | 锁加幂等,即使重复触发也不产生脏数据,见 定时任务运维 |
一条实用原则:能用唯一约束或原子更新解决的,不要引入分布式锁。锁引入了新的依赖、新的故障模式和新的运维成本。
常见坑
- 锁不设过期时间:一次宕机换来永久死锁。
- 过期时间小于任务耗时:静默并发,没有任何报错。
- 用异步复制的缓存做严格互斥:主从切换时锁复活。
- 释放锁时不校验持有者标识:删掉了别人刚拿到的锁。
- 把锁当作正确性的唯一保障:没有幂等兜底,一次窗口就产生脏数据。
常见问题
用缓存做分布式锁够用吗?
对「减少重复执行」这类需求通常够用,前提是业务侧有幂等兜底。若要求严格互斥(如资金操作),应使用带会话与租约的共识组件,或直接依赖数据库的事务与唯一约束。
锁的过期时间该怎么设?
取任务耗时的 P99 再留出明显余量,同时配合续期机制。如果任务耗时本身波动很大,更好的做法是把任务拆小,而不是把过期时间设得越来越长——过期时间越长,宕机后的阻塞时间也越长。
多实例定时任务,该用锁还是靠幂等?
两者都要。锁负责减少重复执行带来的资源浪费,幂等负责保证即使重复执行也不产生错误数据。只有锁没有幂等,迟早会在租约窗口上翻车。
fencing token 是不是必须的?
在写入方可以配合的场景下强烈建议实现,它是唯一能在存储侧挡住过期持有者的通用手段。做不到时,必须用唯一约束、状态机或条件更新等幂等手段替代,不能只依赖锁本身。
资料来源
主流共识与协调组件(如 ZooKeeper、etcd)官方文档中关于会话、租约与选主的说明,Redis 官方文档中关于分布式锁实现及其局限的讨论,以及分布式系统中租约与隔离机制的公开资料。本文为通用工程说明,仅供参考,具体方案请结合一致性要求与故障容忍度选择。
相关阅读
网站访问日志留存与安全合规运维要点
为什么要留日志:这是法定要求 《网络安全法》第二十一条明确要求网络运营者"采取监测、记录网络运行状态、网络安全事件的技术措施,并按照规定留存相关的网络日志不少于六个月"。已完成备案、对外提供服务的网站属于网络运营者范畴,日志留存不是可选项,而是基础合规义务。 应留存哪些日志 | 日志类型 | 记录内容 | 主要用途 …
网站新增域名如何补充接入备案
企业在原有网站基础上新增域名,比如启用新的品牌域名或拼音域名指向同一网站时,不能直接绑定使用,而是需要在原备案基础上补充办理新增域名的接入手续。 新增域名前的准备工作 新增域名前,建议先确认该域名已经完成实名认证,可以通过 Whois查询 核对域名的注册信息和实名状态,避免因域名信息未实名导致接入申请被退回。同时确认…
备案信息年度核查该如何配合应对
部分省份的通信管理部门会对辖区内已备案网站开展年度或不定期核查,核查方式包括系统比对、电话回访、短信确认等,目的是确认备案信息与网站实际运营情况是否一致。 核查通常关注哪些内容 年度核查一般围绕主体信息、网站信息、接入信息三个维度展开,具体可以对照下表自查: | 核查维度 | 常见核查点 | | --- | --- …
备案号在网站上的规范展示与使用要求
网站完成备案只是第一步,备案号在页面上的展示方式同样需要长期维护,很多主体正是因为展示细节不规范,在日常巡查或年度核查中被要求整改。 展示位置与基本要求 通常做法是将备案号放置在网站首页底部,文字需清晰可辨、不被图片或广告遮挡,且格式应与下发的备案号文本保持一致,不能随意增减字符或调整顺序。是否需要加超链接指向查询入…
备案注销之后重新申请要注意什么
有些主体在此前因业务调整、接入商变更等原因注销了原有备案,之后又因新的业务需要重新申请备案。这种“二次备案”与首次备案在流程上大体相似,但有几个环节容易被忽略。 重新申请前的自查 重新申请前,建议先用 ICP备案查询 确认原备案是否确实已经完成注销,避免出现原备案未彻底清空、新申请与旧记录冲突的情况。同时检查计划使用…
备案信息变更有没有时效要求
备案不是办理完成后就一劳永逸的事项,主体信息、网站信息或联系方式一旦发生变化,通常需要在信息变化后的一定时间内完成变更提交,具体时限以属地管局要求为准。 哪些变化需要及时申报 常见需要变更的情形包括:主办单位名称或证件信息变化、网站负责人更换、联系电话或邮箱失效、网站域名调整、网站内容服务类型发生实质变化等。这类变更…
公司迁址之后备案地址信息如何更新
企业办公地址或注册地址发生变化后,备案信息中登记的地址项也需要相应更新,尤其是当迁址涉及跨区、跨市甚至跨省时,办理流程会比同城内迁址更复杂一些。 迁址后需要关注的信息 迁址后首先要确认工商登记信息是否已经完成同步变更,备案地址一般以工商登记的最新地址为准。可以先用 ICP备案查询 查看当前登记的主办单位地址,与最新的…
备案预留手机号邮箱变更该如何更新
备案信息中登记的手机号和邮箱,是管局与接入服务商联系网站负责人的主要渠道,用于发送核查通知、验证短信、审核结果等重要信息。这些联系方式一旦更换却未同步更新,容易导致关键通知被漏收。 常见需要更新的场景 负责人更换手机号或离职导致原号码停用; 企业邮箱系统迁移,原邮箱地址不再使用; 备案负责人变更,联系方式随之更换。 …