优化 1.1.1.1 缓存,省下 100TB 内存

Saving 100 terabytes of memory by optimizing 1.1.1.1's DNS cache

优化 1.1.1.1 缓存,省下 100TB 内存

Cloudflare 的 Big Pineapple 平台承载着 1.1.1.1 等核心 DNS 服务,时刻存储着超过 2500 亿条缓存记录。在这个规模下,单条记录浪费 1 字节就意味着整个集群损失 250GB 内存。我们通过五次连续的内存存储优化,将单条记录的占用空间削减了 50% 以上。这不仅释放了约 100TB 的内存,相当于 130 台 Gen 13 服务器的 RAM 总量,还意外提升了性能:插入吞吐量增加 43%,查询延迟降低 19%。我们证明了在极致优化下,节省空间与提升速度并非零和博弈,而是可以兼得。

更少的内存分配和更好的内存局部性意味着我们并没有为了节省空间而牺牲速度。
  1. lpapez

    这才是交付软件的正确方式。

    先做出能用的产品,验证想法,稳定业务,开始盈利,然后你才能着手优化成本。

    事实上,优化是整个过程里最容易的部分,因为这个 HN 帖子里有很多系统编程专家,他们觉得这些优化简直小菜一碟。

  2. irdc

    这就是为什么系统编程依然重要。

    不过看起来他们漏掉了一个显而易见的优化:把记录数据直接放在 CacheEntry 成员后面,而不是单独分配内存。但这可能只是我这个 C 程序员在瞎操心,在 Rust 里这么做或许没那么容易。

  3. strenholme

    在我自己的 MaraDNS 项目中,我通过一次巨大的 malloc() 调用为黑名单条目分配内存,然后遍历这块内存区域来查找潜在的黑名单条目,从而激进地优化了内存占用。

    当我以前为每个条目单独调用一次 malloc() 时,一个大型黑名单会占用 237 兆字节的内存。而优化为单次 malloc() 调用加载后,同样的黑名单仅占用了 9.5 兆字节。

    https://samboy.github.io/blog/entries/MaraDNS.html#BlogEntry...

  4. vinkelhake

    这些看起来都是减少内存占用的一些相当标准的方法。我不禁在想,将几个独立的列表以某种方式合并成一个列表的做法,可能会削弱 Rust 的安全保证。

    如果你之前有三个独立的 Vec 对象,Rust 能保证你不会越界索引。但现在如果你把所有这些对象放入一个 Vec 并依赖偏移量,你就打开了大门,导致对这些子切片进行越界索引时不会触发 panic。

    这只是个小问题,并不能真正否定这种优化,但我惊讶于文章没有提到这一点。

  5. BikiniPrince

    关于 Cloudflare 有个有趣的事。我有一个 DNS 预热脚本,使用他们排名前 1k 或 10k 的地址。然后当我的主节点启动时,它会预热整个缓存。其他一切使用 memcache,所以整个集群热乎乎的。据我所知,没人像他们那样发布域名统计数据。

  6. bhouston

    当我把 MacBook 的 DNS 服务器覆盖为 1.1.1.1 或 8.8.8.8 时,在使用公共 Wi-Fi 时遇到过问题。我相信这是因为强制门户(captive portals)需要自定义解析 captive.apple.com 这个域名。而外部 DNS 服务器无法将其正确解析到本地网关的授权页面。

  7. 1saadcodes

    我们终于开始更多地欣赏这种类型的工程了。并不是所有问题都需要通过堆砌更多硬件来解决。

  8. ManBeardPc

    Record 结构体包含 rtype 和 data,其中 RecordData 是一个标签联合(tagged union)。这两者难道不是始终同步的吗?我不是 DNS 专家,只是好奇这是否是冗余的,还是有某种原因需要两者并存。如果他们存储的是已经序列化的数据,那这点就不重要了,但我还是想知道当初为什么设计成这样。

同日更多故事

2026-08-27