用户登录

技术文章

外部链接将在新标签页打开。

DNS 区域改为定向构建:从整区重建迁移前要定的验证顺序

一句话回答

定向构建的关键不是先缩小重建范围,而是先证明最小构建与全量构建在 Quicksilver 键值上逐字节一致,再依次验证事件分类、共享元数据、执行时数据漂移、Kafka 合并和超大区例外。无法证明安全时必须回退全量构建。

把 DNS 区域从整区重建迁移到定向构建,第一件事不是给事件补字段,也不是先按记录类型分流,而是确定一套验证顺序:先证明“最小构建”与“全量构建”在边缘可读数据上等价,再逐层处理不确定性。顺序颠倒,定向构建很容易把“不知道”误判成“不用做”,留下过期记录或错误元数据。

Cloudflare 在 2026 年 11 月 2 日的这篇文章中介绍了其 Zone Builder 从整区重建转向定向构建的过程。原文片段说明,每个事件都会启动一个计时,衡量变更转化为权威 DNS 服务器可用数据需要多久,这个工作称为一次 build;build 会读取数据库状态、转换为边缘格式,并写入 Quicksilver。下文只使用该片段支持的事实,并把工程建议与原文实现分开标注。

全量构建是安全基线,也是成本来源#

旧的全量构建有一个重要优点:它不需要知道区域为什么变化,只读取当前区域和设置、读取区内每一条 DNS 记录、转换为 Quicksilver 键、与现有键比较,再删除过期键、写入变化键并更新元数据。最终写入的虽然只是变化部分,但读取、编码、比较和内存占用仍覆盖整个区。对小型区这很便宜;对拥有数千万条记录的大型区,整区甚至无法同时放进内存。

记录级定向构建此前已经存在,真正的难点是 zone setting 事件。一个设置变化可能没有说明“为什么变”,也可能影响多个同名区域共享的数据。原文称,改造后全量构建减少 40%,峰值内存下降 85%,构建延迟减半;这些是 Cloudflare 的生产指标,不是迁移后的默认收益。

迁移前按五道闸门验证#

1. 先证明输出等价,再谈缩小范围

验证对象应是 Quicksilver 中的键和值,而不是数据库查询结果。原文给出的硬规则是:定向构建写入的每个键,必须与全量构建逐字节一致;如果无法证明这一点,就做全量构建。

删除语义要单独验证。原文说明,记录事件包含被删除的记录和更新前的版本;Zone Builder 会按每个重建名称扫描 Quicksilver 中已有的键,删除新构建没有写入的旧键。测试至少要覆盖新增、修改、删除最后一条记录、改名,以及记录键与元数据键同时变化的场景。不能只比较记录值,还要比较共享元数据键。

2. 验证事件是否说清了影响面

原文要求事件生产方带上变化的区域字段和设置,并尽量提供旧值与新值;然后沿生成 DNS 输出的代码路径,逐个追踪设置能影响什么。Universal SSL 是典型例子:启用或关闭它会更新元数据,还可能改变区域顶点(如 example.com)的 CAA 记录,而 CAA 记录用于告诉证书颁发机构是否可以为其签发证书。

但并非所有事件都足够具体。仅更新时间戳的数据库函数、缺失细节、未知事件,或任何可能影响区内任意记录的变化,仍应触发全量构建。原文的原则是:规划器绝不把不确定性转化为更少的工作。验证时要专门构造负向用例,确认这些输入会回退全量,而不是被错误地分到最小构建。

3. 验证同名域共享的元数据

Quicksilver 按区域分开存储记录键,但同一个域名下的多个 Cloudflare 区域共享一个元数据键。这个键像目录,告诉权威 DNS 服务器查询时可以使用哪些内部区域 ID。客户上下线或其他生命周期变化期间,同一个公开域名可能短暂存在多个区域对象,系统按优先级策略只发布一个有界集合。

因此,NS 和通配符变更不能只改记录键,还必须重建共享元数据。原文的做法是:执行时重新读取当前列表;如果要写元数据键,就从最新视图整体重建,而不是在旧副本上打补丁;先写触发区域的记录,再写引用这些记录的元数据。

验证重点包括:同名多区域的 NS/通配符变更、元数据目录的完整重建、记录与元数据的写入顺序,以及 Purge 场景下不误删同名其他区域的目录信息。最后一项是迁移前应主动验证的风险点,不能仅凭“删除区域”这一动作推断安全。

4. 验证执行时的数据漂移与 Kafka 合并

事件描述的是过去,而构建可能等待,数据库也可能继续变化。原文说明规划发生两次:事件先产生一个保守的工作清单;真正执行前,Zone Builder 再读取新的发布快照。抓取片段在这里被截断,后续快照比对和冲突处理细节没有提供,不能替原文补全。

验证应覆盖延迟事件、重复事件、执行前再次修改、删除后重建和跨分区重试。最终边缘状态应符合系统明确的一致性模型,而不是简单等于“第一个事件到达时的状态”。此外,新调度器会合并同一区域的工作,但合并不等于可以丢消息。需要验证聚合、重试、幂等和顺序处理;原文也提醒,全量构建重试会阻塞同一 Kafka 分区上的其他变更,这是必须纳入故障演练的阻塞风险。

5. 验证超大区例外与人工兜底

原文保留了一个例外:当区域超过固定记录数阈值时,Zone Builder 不再升级为全量构建,而是重建顶点、元数据和排队事件中列出的所有名称。原文明确说这是权衡,因为这类超大区的全量构建无法完成,且重试会阻塞分区;少数遗漏场景可以手动重建个别名称。

这个例外必须单独验证:阈值边界、排队事件是否覆盖所有受影响名称、同名多区域、首次发布,以及无法证明安全的设置变更。若不能保证不漏名称,就不能把它当成默认路径。定向构建的准入条件不是“事件很多”,而是“每个被缩小的构建都能被证明安全”。

五类构建的验证重点#

构建类型重建范围典型触发验证重点
仅资源指定 DNS 名称的记录,不修改元数据普通 A、AAAA、TXT、CNAME 变更输出等价、旧键删除、名称范围准确
资源与元数据指定名称及共享元数据NS、通配符变更元数据整体重建、同名多区域目录
顶点与元数据区域顶点及元数据Universal SSL 等设置顶点 CAA 等派生记录、设置影响面
清除移除不再发布的区域区域下线不误删同名其他区域的共享目录项
全量区域全部记录无法证明更小构建安全、首次发布内存、重试阻塞、超大区例外

上线顺序与观测指标#

建议按“影子比对、普通记录、元数据类变更、大区、放量”的顺序推进。影子比对是指同一事件分别计算全量与定向结果,只比较、不写入;这一步能先暴露键值差异,而不把风险带到边缘。每个阶段都应保留按区域粒度的全量回退开关。

观测项至少包括:全量构建次数与占比、回退原因、未知事件数量、峰值内存、从事件到写入 Quicksilver 的延迟、重试与分区阻塞时长、Purge 相关告警。对 API 层,建议区分“事件已接收”“构建中”“已写入 Quicksilver”,不要把异步构建的接收成功表达成边缘已经生效。

适用边界#

这套顺序适用于已有全量构建基线、准备按事件缩小重建范围的 DNS 发布系统。若缺少可靠的键值等价比对、明确的事件分类或可回退开关,应先保留全量路径。原文片段还提示了两个边界:执行前快照之后的冲突处理没有在材料中展开;超大区例外依赖人工兜底,并非无条件安全。涉及具体实现和完整指标口径,应回到原文及自家系统验证。

结论#

迁移到定向构建,正确的顺序是:先证明输出等价和删除正确,再验证事件能否描述影响面;随后处理共享元数据、执行时漂移、Kafka 合并与超大区例外;最后才用灰度指标换取性能。只要某一步无法证明安全,就应退回全量构建。定向构建的价值来自“可证明的最小工作”,不是“尽量少做工作”。

参考来源

  1. How we halved DNS build delay and cut memory use by 85%

以上为本文写作时的参考资料,引用观点以原文为准。

作者:沐小悠

本文约 8 分钟读完 · 关键词:DNS 定向构建、全量构建、Quicksilver、Zone Builder、Kafka

更多文章 GET 示例接口