Cloudflare нашла способ освободить около 100 ТБ оперативной памяти на своих серверах, просто изменив то, как DNS-кэш хранит данные.
Инженеры последовательно оптимизировали структуры данных в платформе Big Pineapple, которая обслуживает 1.1.1.1 и другие DNS-сервисы компании. В результате память освободилась, а сам кэш стал работать быстрее.
Читают прямо сейчас:
Промт-инженер: самый лёгкий вход в программирование с ИИ — разница между «мясным прокси» и настоящим промт-инженером: один копирует, другой формулирует, проверяет и адаптирует
Галлюцинации ИИ: почему LLM врут и как с этим бороться — почему проверять ответ нейросети перед отправкой — это не паранойя, а базовый профессиональный навык
Вайбкодинг и безопасность: 3 реальных кейса из продакшена — что происходит, когда сгенерированный код уходит в продакшен без понимания того, что там написано
250 млрд записей превращают мелкие потери в большие
Big Pineapple одновременно хранит более 250 млрд DNS-записей. При таком масштабе даже один лишний байт на запись превращается более чем в 250 ГБ занятой памяти.
Cloudflare решила проверить, сколько памяти на самом деле тратится на каждую запись. Для этого инженеры создали тестовый кэш, похожий на рабочую нагрузку компании. Далее они измерили как объем памяти, так и скорость добавления и поиска записей.
Первой проблемой оказались стандартные структуры Rust. Например, Vec хранит не только сами данные, но и информацию о выделенной емкости. Для DNS-кэша это лишнее — после сохранения ответа его содержимое больше не меняется.
Поэтому инженеры заменили изменяемые структуры на компактные варианты, которые не резервируют место для будущего роста. Только это изменение позволило сэкономить более 15 ТБ памяти.
Меньше указателей и повторяющихся данных
Затем Cloudflare объединила несколько списков DNS-записей в один массив. Вместо полноценных указателей и длин массивов для отдельных секций ответа теперь используются небольшие смещения.
Отдельно инженеры избавились от повторяющихся имен доменов. В большинстве DNS-записей владелец записи совпадает с доменом, который запрашивал пользователь. Поэтому хранить одно и то же имя несколько раз нет смысла — его можно восстановить из ключа кэша.
Еще одна проблема обнаружилась в enum Rust. Размер такого типа определяется его самым крупным вариантом. Поэтому распространенная IPv4-запись, которой достаточно всего четырех байт, могла занимать значительно больше места из-за крупного варианта того же enum.
Cloudflare сначала вынесла большие варианты в отдельные области памяти, а затем пошла дальше и стала хранить данные DNS-записей в компактном массиве байтов. Это позволило сократить число отдельных выделений памяти и улучшить локальность данных для процессора.
К слову, именно в такие моменты хорошо видно, почему в разработке на больших системах важны не только сами языки программирования, но и понимание того, как устроены память, структуры данных и алгоритмы. В каталоге по ссылке эти темы становятся частью практической работы с кодом.
Память сократилась на 56%
В результате пяти последовательных оптимизаций размер одной записи в тестах уменьшился с 953 до 420 байт. А это, между прочим, 56%! Объем выделяемой памяти на одну запись снизился с 1,1 КБ до 461 байта.
В реальной инфраструктуре эффект оказался немного меньше, поскольку оперативную память занимают не только данные DNS-кэша. Тем не менее после завершения развертывания, Cloudflare получила примерно 100 ТБ свободной памяти по всей своей инфраструктуре.
При этом оптимизация не привела к компромиссам по скорости. Напротив, производительность выросла: скорость добавления записей увеличилась на 43%, а задержка поиска уменьшилась на 19%.
