
Cloudflare 将 DNS 构建延迟减半并降低 85% 内存占用
来源标题:We halved DNS build delay and cut memory use by 85%
Cloudflare 优化 DNS 传播管道中的 Zone Builder,将构建延迟减半、内存使用降低 85%。该组件目前每秒处理约 700 次 DNS 记录变更,较 2022 年的 250 次增长近三倍,部分 zone 记录数已超 2000 万。
以下正文由 AI 翻译自 Hacker News(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。
2022年我上次撰文介绍 DNS 传播管道时,Zone Builder 每秒大约接收 250 条 DNS 记录变更。如今它每秒接收约 700 条,接近原来的三倍,此外还有约 100 个其他事件,例如区域设置变更。然而,事件数量从来都不是真正的问题。问题在于其中一些事件所需要的那类工作,以及这类工作如何随着区域规模增长而增长。现在有些区域容纳了超过 2000 万条记录,我们预计它们会继续增长,朝着数亿条迈进。
每个事件都会启动一个计时器,衡量我们将该变更转化为权威 DNS 服务器可使用的数据需要多长时间。我们把这部分工作称为一次构建(build)。一次构建会读取当前数据库状态,将其转换为边缘使用的格式,并将任何变更写入 Quicksilver。
2022 年,单记录构建平均比全量构建快 150 倍。在一个拥有 100 万条记录的测试区域上,单记录构建快了 4,250 倍。我们在那篇文章结尾提出了显而易见的下一步:对区域设置做同样的事情。
为什么 Zone Builder 不直接重建发生变更的那项设置呢?
它应该这样做,而这正是我们最终实现的方向。然而,证明何时这样做是安全的,占据了大部分工作。记录事件会指明变更了什么。区域事件可能来自许多 Cloudflare 产品,可能不会说明区域为何变更,并且可能改变多个同名区域共享的数据。选择过多的工作会浪费容量。选择过少则可能在边缘留下过时或不正确的 DNS 数据。
我们构建了一个定向构建规划器,它选择我们能证明安全的最小构建,还构建了一个新的调度器,将同一区域的工作合并。区域设置变更不再重建拥有数千万条记录的区域。两者结合,将峰值内存降低了 85%,而额外的余量让我们能够安全地缩短管道一直以来为弹性而需要的等待时间,将从 DNS 变更到其数据写入 Quicksilver 的时间减半。
DNS 区域是某个域名的记录和设置的集合。Cloudflare 使用多阶段管道将该区域的变更转化为全球网络中可用的数据。
这是一个简化视图。Zone Builder 不会直接将数据库行复制到边缘。它将记录与区域设置结合,应用 DNS 服务规则,并组织结果,以便我们的权威 DNS 服务器能够快速读取。
最初的 Zone Builder 有一个有用的特性:它不需要知道区域为何变更。它从当前数据库状态重建期望状态。
最终写入只包含发生变更的键。然而,全量构建仍然会读取、编码并比较每一条记录,并在这样做时将整个区域保存在内存中。对于小区域来说这很廉价。对于我们最大的区域,拥有数千万条记录,区域根本无法放入内存。我在下文解释我们如何处理这种情况。
区域设置使定向构建更加困难。Universal SSL 就是一个例子。启用或禁用它都会更新元数据,并可能更改区域顶点(即裸域名,例如 example.com)处的证书颁发机构授权(CAA)记录。CAA 记录告知证书颁发机构他们是否可以为该域名颁发证书。
全量构建只需要知道区域发生了变更。定向构建必须回答三个问题:
安全地回答这些问题意味着解决五个问题,本文其余部分将按顺序逐一介绍:
我们修改了事件生产者,使其包含发生变更的区域字段和设置,并在可用时附带旧值和新值。然后,我们在生成 DNS 输出的代码中追踪每项设置,并对其可能影响的内容进行分类。
并非每个事件都如此具体。有些数据库函数只更新一个时间戳,实际上是在说“这个区域有某些东西变了”。有时这是无害的簿记操作。有时这意味着其他地方的数据发生了变化,必须重新读取。
这些情况在事件中看起来完全相同。在我们能够识别调用方及其目的之前,仅更新时间戳仍会触发全量构建。同样的规则适用于缺失细节、未知事件,或任何可能影响区域内任何位置记录的变化。规划器绝不会将不确定性转化为更少的工作。
Quicksilver 输出有两个在此处重要的部分。记录键包含某个区域和名称的 DNS 答案。一个较小的共享元数据键告诉我们的权威 DNS 服务器如何使用该区域,包括在哪里找到特殊记录,例如名称服务器和通配符。有些事件只更改记录键;其他事件必须同时更新两者。
有了这种区分,规划器可以选择五种构建类型之一:
规则很简单:定向构建写入的每个键都必须与全量构建写入的内容逐字节完全相同。如果我们无法证明这一点,就进行全量构建。
移除旧状态的工作方式与 2022 年单记录构建相同。记录事件包含已删除的记录和已更新记录的先前版本。然后,Zone Builder 会扫描 Quicksilver,查找其重建的每个名称下的现有键,移除新构建未写入的任何键。
当变更可能影响区域内任何位置的记录,或区域可能需要首次发布时,全量构建仍然是必要的。
(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)
正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。