Cloudflare a annoncé les résultats d’une série d’optimisations de bas niveau du cache DNS de la plateforme Big Pineapple, qui exploite 1.1.1.1, Gateway DNS, DNS Firewall, AS112 ainsi qu’un certain nombre d’autres services DNS. La plateforme stocke plus de 250 milliards d’entrées DNS à tout moment ; ainsi, supprimer un seul octet par entrée permet d’économiser plus de 250 gigaoctets de mémoire à l’échelle du parc.
Cinq changements successifs dans la structure de données écrite en Rust ont réduit la taille d’une entrée de 953 octets à 420 octets, soit une baisse de 56 %. Après le déploiement généralisé de ces changements, la mémoire de l’ensemble de travail utilisée sur le parc de Cloudflare a diminué d’environ 100 téraoctets, avec une amélioration des performances plutôt qu’un compromis : le débit d’insertion des entrées a augmenté de 43 % et la latence de recherche dans le cache a diminué de 19 %.
Pourquoi la taille d’une entrée DNS était-elle importante ?
Big Pineapple démarre avec un cache vide, puis celui-ci se remplit à mesure que les requêtes arrivent jusqu’à atteindre sa limite maximale ; les entrées les plus anciennes ou les moins utilisées sont alors supprimées. La taille du cache varie selon les centres de données, et l’utilisation d’EDNS Client Subnet peut entraîner le stockage de plusieurs réponses pour une même requête, car les serveurs faisant autorité peuvent fournir des réponses différentes selon le réseau du client.
Chaque entrée se compose d’une clé qui détermine le nom de domaine, le type d’enregistrement et certains attributs, ainsi que d’une valeur contenant une réponse DNS, les sections authority et additional, et des métadonnées telles que l’heure de création, un compteur d’utilisations et la durée TTL. À cette échelle, les champs superflus ou l’espace réservé ne constituent plus de petits détails internes, mais deviennent un coût opérationnel considérable.
D’où venaient les économies ?
Cloudflare a remplacé les structures Vec et String extensibles par des structures de taille fixe, Box<[T]> et Box<str>, après le stockage de la réponse, car les données ne sont plus modifiées par la suite. Ce changement a supprimé le champ de capacité conservé par les structures extensibles et limité l’espace réservé inutilisé. Comme chaque entrée contient huit champs de ce type, l’économie a atteint 64 octets par entrée, soit plus de 15 téraoctets sur l’ensemble du cache.
Les listes des sections answer, authority et additional ont également été regroupées en une seule liste, avec l’utilisation d’offsets de type u16 au lieu de pointeurs et de longueurs plus grands. Cela a permis d’économiser 28 octets par entrée. La structure a aussi tiré parti du regroupement de plusieurs champs booléens dans un seul bitflag, ce qui a réduit l’espace gaspillé en raison de l’alignement mémoire imposé par Rust au sein des structures.
Dans la plupart des enregistrements DNS, le propriétaire de l’enregistrement correspond au domaine interrogé. Cloudflare ne stocke donc plus le nom complet du propriétaire dans ces cas, mais le reconstruit à partir de la clé de stockage lors de la construction de la réponse. Lorsque le nom diffère, comme pour les enregistrements CNAME, le nom complet est stocké. Les allocations mémoire pour la plupart des noms de propriétaires ont ainsi été supprimées, tout en conservant les cas où le nom est réellement nécessaire.
Réduire le coût des grands types d’enregistrements
La structure RecordData utilisait une enum dont la taille était égale à celle du plus grand type d’enregistrement, à savoir NAPTR, avec 144 octets après prise en compte du tag et de l’alignement. Par conséquent, les enregistrements A, qui ne nécessitent que 4 octets, et les enregistrements AAAA, qui en nécessitent 16, occupaient beaucoup plus d’espace que nécessaire, alors que A et AAAA représentaient plus de 80 % du trafic de test.
Le placement des grands types dans une Box séparée a été testé ; il réduisait le gaspillage pour les enregistrements A et AAAA, mais ajoutait des allocations distinctes et des problèmes de localité mémoire. La solution finale a consisté à stocker les données des enregistrements elles-mêmes sous forme d’octets bruts contigus dans une Box<[u8]>, avec un préfixe de longueur de deux octets pour chaque enregistrement. Cela a supprimé le coût de l’enum et des allocations multiples, tout en améliorant l’utilisation de la mémoire cache du processeur.
Ce choix signifie que les enregistrements ne sont plus indexables de manière aléatoire et doivent être parcourus séquentiellement. Cloudflare estime que le coût est limité, car le nombre d’enregistrements par entrée est faible. La plupart des types, notamment A, AAAA, TXT et les enregistrements DNSSEC, peuvent également être copiés directement dans le message DNS sortant, tandis que les types contenant des noms de domaine, comme CNAME, NS, MX et SOA, nécessitent toujours une analyse afin d’appliquer la compression des noms DNS.
Qu’est-ce qui a changé en pratique ?
Les mesures en production ont montré une baisse de la mémoire résidente au 99e percentile, de 9,3 à 5,3 gigaoctets, soit 43 %, et de 6,5 à 3,8 gigaoctets au 90e percentile, soit 42 %. Le nombre d’allocations par entrée est passé de 1,1 kilooctet à 461 octets, tandis que le débit d’insertion est passé de 625 000 entrées par seconde à 893 000, et que la latence de recherche a diminué de 828 nanosecondes à 670 nanosecondes.
Le déploiement des changements a commencé le 18 mai 2026 et s’est achevé sur l’ensemble des services le 6 juillet 2026. Cloudflare précise que la mémoire résidente en production comprend d’autres données en plus du cache ; le pourcentage de baisse réel à l’échelle du processus a donc été inférieur au résultat de la mesure isolée par entrée. L’entreprise prévoit également de réinvestir la mémoire libérée pour augmenter la capacité du cache sans accroître la consommation mémoire, afin d’améliorer les taux de réussite du cache et de réduire les requêtes envoyées aux serveurs en amont.
L’importance de ce cas tient au fait qu’il montre que les optimisations de la structure des données, comme la suppression de la capacité superflue, le regroupement des allocations et l’amélioration de la localité, peuvent avoir un effet supérieur à celui d’un ajout direct de ressources matérielles lorsqu’un service fonctionne avec des centaines de milliards d’éléments. Certains compromis subsistent toutefois : le stockage brut accroît la complexité de la gestion des enregistrements, la récupération depuis la clé de stockage devient nécessaire pour reconstruire les noms des propriétaires, et les résultats des tests reposent sur un mélange de trafic donné qui ne correspond pas entièrement à la production. Les mesures en production restent donc la référence la plus importante pour évaluer ce type d’optimisation, et non les seuls chiffres théoriques.