8月28日、Luke Jamesが「Cloudflare frees up 100TB of RAM by shrinking 1.1.1.1's DNS cache entries」と題した記事を公開した。内容は、CloudflareがDNSキャッシュエントリのメモリレイアウトをRustレベルで再設計し、ハードウェアを一切変えることなくグローバルフリート全体で約100TBのRAMを解放したという技術的な取り組みだ。
サーバー増設でも新型チップへの移行でもなく、データ構造の見直しだけで大企業のインフラが変わる——この事実が、CloudflareのシステムエンジニアSebastaan NeuteboomがCloudflare公式ブログに投稿した技術解説として話題を集めている。
1エントリあたり533バイトの削減が100TBになる理由
Cloudflareの1.1.1.1リゾルバの背後にある分散キャッシュプラットフォーム「Big Pineapple」は、常時2500億件以上のDNSキャッシュエントリを保持している。Big Pineappleはグローバルに分散したCloudflareのPoPサーバー群上で動作し、DNSキャッシュをメモリ上に維持するインメモリストアだ。この規模では、1エントリあたりわずか1バイトの無駄が250GB以上のフリートメモリ消費に直結する。
今回の取り組みでは、Rustレベルでの複数の変更によってキャッシュエントリを953バイトから420バイトへ縮小した。ハードウェアには一切手を加えず、純粋にデータ構造の再設計だけで達成した成果だ。削減量はCloudflareが運用する第13世代サーバー(1台あたり768GB DDR5-6400搭載)約130台分のRAMに相当する規模となる。
Rustレベルの主な変更の中身
最大の一手はVecとStringの廃止だ。RustのグロウアブルコンテナであるVecとStringは内部に「容量(capacity)」フィールドを持つ。これはデータが動的に追加される際には必要だが、一度キャッシュに格納されたDNSエントリは書き換えられない。つまり、容量フィールドは二度と使われないデータとしてメモリを占有し続けていた。これを固定サイズのボックス化スライス(boxed slice)に置き換えるだけで、この1つの変更だけで15TB超のRAMが解放された。
次に大きかったのが、3つのレコードリストの統合だ。DNSレスポンスに含まれるANSWER・AUTHORITY・ADDITIONALの3種類のレコードリストがそれぞれ独立したメモリ領域に保持されていたものを、単一の連続バッファにまとめ、2バイトオフセットでインデックスする構造に変更した。
さらに、レコードデータのワイヤーフォーマット格納も効果が大きかった。変更前は、4バイトで表現できるAレコード(IPv4アドレス)でも、Cloudflareがキャッシュする最大レコード型であるNAPTR(Naming Authority Pointer)レコードと同じ144バイトの領域を占有していた。これを長さプレフィックス付きのワイヤーフォーマット生バイト列として格納することで、各レコードが実際のサイズだけを使うようになった。
そのほかの変更として、クエリしたドメイン名と重複する「オーナー名」をキャッシュから削除して読み出し時に動的再構築する方式への変更も実施している。また、Rustの型システムを活用したフィールドのアライメント最適化によるパディング削減も組み合わせている。
メモリだけでなく速度も改善
この再設計はメモリ削減にとどまらず、スループットとレイテンシにも好影響をもたらした。以下はBig Pineappleの単一インスタンスを対象にした内部ベンチマークの結果だ。
| 指標 | 変更前 | 変更後 |
|---|---|---|
| インサートスループット | 625,000エントリ/秒 | 893,000エントリ/秒(**+43%**) |
| ルックアップレイテンシ | 828ナノ秒 | 670ナノ秒(**-19%**) |
| p99 常駐メモリ(インスタンスあたり) | 9.3GB | 5.3GB |
レコードデータが連続メモリに詰め込まれたことでCPUキャッシュのローカリティが向上し、大半のレコード型では格納バッファから送信レスポンスへ直接コピーできるようになった点も寄与している。ロールアウトは5月中旬から7月初旬にかけて段階的に実施された。
解放されたRAMの使途
解放された100TBのRAMは、サーバー台数の削減や小型構成への移行には充てられない。Cloudflareはより大きなDNSキャッシュの確保に使う方針だ。キャッシュが大きくなればヒット率が上がり、上流の権威DNSサーバーへのクエリトラフィックを削減できる。エンドユーザーにとっては名前解決の高速化という形で恩恵が届く。
これはCloudflareにとって大規模なメモリ回収を意識した近年の取り組みの一環でもある。以前にはリクエスト処理レイヤーをRustで書き直した「FL2」プロジェクト(Cloudflareブログ参照でも同様のアプローチで成果を上げており、データ構造レベルの最適化をインフラ改善の主軸に据える姿勢が見て取れる。
詳細はCloudflare frees up 100TB of RAM by shrinking 1.1.1.1's DNS cache entriesを参照していただきたい。