Cloudflare высвободила 100 ТБ оперативной памяти оптимизацией DNS-кэша

27 августа в Cloudflare рассказали о событии из разряда «однострочный патч с мультипликативным эффектом»: небольшая экономия памяти на одной структуре данных, будучи умноженной на сотни миллиардов экземпляров, превращается в десятки терабайт. Правда, в данном случае одним однострочным патчем дело не ограничилось — инженеры последовательно внесли пять сравнительно небольших изменений в представление записей DNS-кэша и в итоге высвободили около 100 ТБ оперативной памяти.
Оптимизации проводились в Big Pineapple — написанной преимущественно на Rust платформе Cloudflare, лежащей в основе публичного DNS-резолвера 1.1.1.1, Gateway DNS, DNS Firewall, AS112 и других DNS-сервисов компании. В каждый момент времени Big Pineapple хранит более 250 млрд записей DNS-кэша, поэтому всего один лишний байт на запись означает более 250 ГБ памяти на всей инфраструктуре.
Cloudflare начала развёртывание изменений 18 мая и завершила его 6 июля 2026 года. Оптимизация состояла из пяти основных этапов:
-
Вместо динамических
VecиStringдля неизменяемых после помещения в кэш данных стали использоватьBox<[T]>иBox. УVecкроме указателя и длины хранится ещё и ёмкость буфера, необходимая для его последующего расширения, но кэшированные DNS-ответы больше не изменяются. В каждой записи находилось восемь подобных полей, поэтому экономия только на этом изменении составила 64 байта на запись и более 15 ТБ в масштабах Cloudflare. -
Три отдельных массива DNS-записей
answer,authorityиadditionalобъединили в один массив, а границы секций стали задавать двумя 16-разрядными смещениями. Это позволило убрать два указателя и две длины и сэкономить ещё 28 байт на запись. Несколько логических полей заодно были упакованы в битовые флаги, что сократило и выравнивающие промежутки внутри структур Rust. -
Из большинства записей перестали сохранять повторяющееся имя владельца DNS-записи. Обычно оно совпадает с доменом, уже присутствующим в ключе кэша. Теперь имя сохраняется отдельно только тогда, когда оно действительно отличается, например для записей за
CNAME, а в остальных случаях восстанавливается из ключа. -
Инженеры обратили внимание на особенности
enumв Rust. Размер перечисления определяется его крупнейшим вариантом: в структуре Cloudflare таким вариантом былNAPTR, из-за которогоRecordDataзанимал 144 байта. При этом наиболее распространённой записиAтребуется всего 4 байта, аAAAA— 16 байт. ПосколькуAиAAAAсоставляют более 80% обрабатываемых записей, большая часть выделенной памяти фактически оставалась пустой. Перенос крупных вариантов в отдельные heap-объекты позволил значительно уменьшить самenum. -
Наконец, от хранения разобранных Rust-структур для содержимого DNS-записей частично отказались вообще. Данные стали помещать в единый
Box<[u8]>практически в сетевом формате DNS, добавляя перед каждой записью двухбайтовую длину. Это убрало множество отдельных выделений памяти и улучшило локальность данных для процессорного кэша. ДляA,AAAA,TXTи DNSSEC-записей данные теперь можно непосредственно копировать в формируемый DNS-ответ, не выполняя повторную сериализацию. Само это изменение уменьшило задержку поиска примерно на 5%, а использование повторно применяемого временного буфера увеличило скорость добавления записей ещё на 13%.
В результате в тестах средний объём памяти на одну запись сократился с 953 до 420 байт, то есть на 56%, а фактически выделяемая память — с 1,1 КБ до 461 байта. На рабочих серверах эффект оказался несколько меньше, поскольку в RSS процесса входит не только DNS-кэш, но итоговая экономия по всей инфраструктуре всё равно составила примерно 100 ТБ оперативной памяти.
Экономия памяти при этом не потребовала жертвовать производительностью. Наоборот, пропускная способность при добавлении записей в кэш выросла с 625 тыс. до 893 тыс. записей в секунду, или на 43%, а задержка поиска снизилась с 828 до 670 нс, или на 19%. В production значение p99 для потребления памяти одним экземпляром Big Pineapple уменьшилось с 9,3 до 5,3 ГБ, а p90 — с 6,5 до 3,8 ГБ.
Высвободившиеся 100 ТБ Cloudflare сравнивает с объёмом памяти примерно 130 серверов поколения Gen 13. Однако вынимать DIMM из серверов компания, естественно, не собирается: свободную память планируется направить на увеличение DNS-кэшей. Более вместительный кэш повысит вероятность нахождения готового ответа и сократит число запросов к внешним авторитетным DNS-серверам.
Big Pineapple создавалась Cloudflare как собственная замена постепенно переросшей свои первоначальные задачи инфраструктуре на основе Knot Resolver. Компания ранее подробно рассказывала, что сервис со временем практически полностью переписали на Rust, а расширяемую часть архитектуры построили вокруг изолированных WebAssembly-модулей.
>>> Источник
