Cloudflare用定向区域构建减少DNS构建工作:自测92.95%的构建跳过全量重建,平均内存从49 GiB降到7 GiB

Published · AI Daily — AI-assisted deep research, methodology & disclosure

Cloudflare在2026年11月2日介绍DNS Zone Builder的定向构建:事件携带变更字段,规划器选最小安全构建,写入的键须与全量构建逐字节一致。无法证明时一般退回全量构建,但超过固定记录数阈值的超大zone从不全量构建,只重建顶点、元数据和事件指明的名称,罕见情况人工修复。其24小时构建类型统计显示92.95%的构建避免整区重建;旧生产调度器与新镜像调度器消费相同事件的24小时并排比较中,典型延迟几乎不变,最大p99峰值从14.6降至1.21分钟,截止写入Quicksilver而不含全球分发。部署整体工作集内存平均从49降至7 GiB、峰值从79降至12 GiB;随后缩短重建间隔和Kafka缓冲后,中位完成延迟约从7.7降至3.3秒。这些均是Cloudflare自测,不是单个zone的保证。

2026年11月2日,Cloudflare发布了Alex Fattouche撰写的工程文章,讲述如何减少DNS区域构建器(Zone Builder)在每次变更后要做的工作。Zone Builder把DNS记录和区域设置的变更转换成Cloudflare权威DNS服务器可以使用的数据,并写入分布式键值存储Quicksilver,再由它分发到全网。作者2022年上一次写这条管线时,构建器每秒收到约250次记录变更;现在约为700次,另有约100个区域设置变更之类的其他事件。文章说,事件的数量从来不是真正的问题,真正的问题是部分事件所需要的工作类型:现在有些区域包含超过2000万条记录,Cloudflare预计它们还会增长到数亿条。

旧设计有一个好处:全量构建不需要知道区域为什么变化。它读取区域和每一条记录,转换成Quicksilver的键,与已存储的内容比较,只写入差异。对小区域来说这很便宜,但它仍然要读取并比较每一条记录,还要把整个区域放进内存。启用Universal SSL这样的区域设置变更,会改动元数据以及区域顶点上的证书颁发机构授权记录,而事件往往没有说明究竟改了什么。因此Cloudflare修改了事件生产者,让事件在可用时带上变更的字段以及变更前后的值,并建造了一个规划器,选择它能证明安全的最小构建。

规划器在五种构建类型中选择:仅资源、资源加元数据、顶点加元数据、清除和全区域。文章给出的规则很严格:定向构建写入的每一个键,必须与全量构建会写入的内容逐字节相同;无法证明这一点时,系统就做全量构建。缺少细节、未知事件和仅更新时间戳的变更仍然触发全量构建,所以不确定性不会变成更少的工作。清理旧状态的方式与2022年相同:记录事件包含已删除的记录和更新前的版本,构建器会在Quicksilver中扫描它所重建的每个名称下已有的键,并删除过期的。对于最大的区域有一个刻意的例外:记录数超过固定阈值后,构建器不再升级为全量构建,因为那样的构建无法完成,还会拖住同一Kafka分区上的其他变更。它改为重建顶点、元数据和事件所指明的记录,极少数情况可以手工修复。

共享名称让问题更复杂。Quicksilver为每个区域单独存放记录键,但对同一域名的所有区域只保留一个共享的元数据键,其中列出哪些内部区域ID可以用来回答查询。在客户接入和退出期间,同一个域名下可能短暂存在多个区域对象。文章还讨论了事件和构建之间数据库可能发生变化时要重新读取,以及在同一个调度器里合并同一区域的工作而不丢失任何Kafka消息。

Cloudflare用三种方式检验安全性主张。等价性测试从同一数据库状态运行一次全量构建和一次定向构建,并比较定向计划所拥有的每个键。上线期间,它还在每次定向构建旁边运行一次全量构建。随后,一个镜像Zone Builder消费生产环境的Kafka流,读取生产数据库状态,但写入不为任何客户提供服务的单独Quicksilver。比较器抽查20%的区域,文章里的仪表盘显示在234,313个匹配的区域中差异率为0.31%,其中多数是时间差。发布按区域名称的哈希分批进行,先免费区域,再付费区域。

24小时构建类型统计显示,约86.81%只涉及资源、2.54%涉及资源和元数据、2.30%涉及顶点和元数据、1.30%为清除,因此92.95%的构建避免重建整个区域,全量构建占7.04%;原先需全量的两类元数据构建占4.84%,加上剩余7.04%,全量构建比例从11.88%下降约40%。另一项并排比较让旧生产调度器和新镜像调度器在同一24小时消费相同事件:典型完成延迟几乎不变,最大p99峰值从14.6分钟降到1.21分钟。完成延迟只计到写入Quicksilver,不含全球分发。Zone Builder整个部署的汇总工作集内存平均从49 GiB降到7 GiB、峰值从79 GiB降到12 GiB,图展示的是发布后的下降,不能自动归入上述24小时窗口。之后Cloudflare缩短每区重建间隔和Kafka Aggregator缓冲,完成延迟中位数才从约7.7秒降到3.3秒。该阶段的粗直方图图表跨度接近两小时;后续约四小时的细直方图显示中位数约3.4秒。

上述各项是Cloudflare按不同阶段和口径报告的自测,不是统一一天的实验,也不能据此断言发生在不同自然日。构建占比的分母是构建次数,部署整体工作集内存不是单次构建内存;并排延迟涵盖各构建类型和套餐,不能作为单个区域的承诺。借鉴的方法是让事件说明变更、验证最小输出与全量输出等价、保留有超大zone例外的安全回退,并在发布前用镜像环境测试。

从工程角度看,这篇文章最有价值的地方是它对“证明”的态度。很多系统为了追求速度会做增量处理,却没有证据证明增量结果和全量结果相同;这里的做法是把相等性写成测试,在上线时同时跑两种构建,再用镜像环境和抽样比较器长期监测,只有在差异类型不再新增时才扩大比例。这套多层校验,比任何单一的性能数字都更能说明这项改动为什么可以放心推广。

Sources

FAQ

这次改动的核心思路是什么?

让变更事件说明改了什么,由规划器选出能证明安全的最小构建,而不是每次重建整个区域。规则是定向构建写入的每个键必须与全量构建逐字节一致,无法证明就退回全量构建,超大区域则只重建顶点、元数据和被指明的记录。

文章报告了哪些主要数字,该怎么看?

24小时内92.95%的构建避免整区重建。同事件并排比较中典型延迟近乎不变,最大p99峰14.6→1.21分钟;部署整体工作集内存均值49→7 GiB。后来调短重建间隔和Kafka缓冲,中位延迟7.7→3.3秒。均为Cloudflare自测。

其他团队可以借鉴什么做法?

先让事件携带变更字段和前后值,把定向构建写入键与全量构建逐字节等价写成测试,并在上线时并行比对、用独立存储的镜像抽样。按哈希逐步放量;无法证明等价时一般回退全量,但超大zone从不全量,只重建顶点、元数据和事件指明的名称,罕见情况人工修复。