HeadlinesBriefing favicon HeadlinesBriefing.com

Cloudflare économise 100 To de RAM avec Rust

Hacker News •
×

Cloudflare opère à une échelle si grande que, même après des années à travailler ici, cela ne semble pas réel. Nous avons des milliers de serveurs partout dans le monde avec des pétaoctets de RAM et des millions de cœurs de CPU, et tout cela est poussé au maximum. Aussi vastes que ces ressources puissent paraître, elles restent finies, et lorsque vous avez besoin que chaque service s'exécute sur chaque nœud, cela ne laisse pas de place au gaspillage. À cette échelle, les petites améliorations sont fortement amplifiées, donc même des améliorations de 1 % à la fois méritent d'être célébrées. Et certains ajustements s'additionnent pour beaucoup plus : dans cet article, nous examinerons comment de petits changements à un seul algorithme ont considérablement réduit l'empreinte mémoire de l'un de nos services basés sur Pingora. Cela nous a permis de récupérer plus de 100 To de RAM à l'échelle mondiale, en plus des 100 To de mémoire que l'équipe DNS a pu libérer le mois dernier.

Ne pas gaspiller Maintenir un partage équitable des ressources entre les équipes n'est pas facile, surtout dans les grandes organisations. L'un des moyens par lesquels Cloudflare garantit que l'équilibre est maintenu est grâce aux efforts inlassables de la merveilleuse équipe Performance. Cette histoire commence par un ticket déposé par Ivan qui a découvert : Utilisation excessive de mémoire par pingora-ketama dans Pingora Backend Router. La conclusion était que notre service interne d'équilibrage de charge, Pingora Backend Router (oui, PBR), utilisait beaucoup plus de mémoire que prévu — en particulier dans les structures associées à pingora-ketama, qui est notre bibliothèque open source pour la gestion du hachage cohérent. Pour parler de la façon dont nous avons traité cette apparente surutilisation de la mémoire, nous devons parler de ce qu'est le hachage cohérent, pourquoi nous l'utilisons dans PBR, et comment il est devenu si gourmand en mémoire. Chemin faisant, nous apprendrons un peu de Rust et même un peu de mathématiques.

Hachage cohérent Le hachage cohérent est une méthode largement utilisée pour répartir les tâches entre plusieurs serveurs d'une manière qui ne nécessite pas de grands changements lorsque des serveurs sont ajoutés ou supprimés. En interne, nous l'utilisons pour acheminer les requêtes cacheables vers les serveurs par URL. Cela nous permet de ne conserver qu'une seule copie d'un fichier stocké par centre de données et offre un moyen stable de trouver l'emplacement de chaque fichier. Nous avons déjà mentionné ce système, mais prenons le temps d'expliquer comment et pourquoi cet algorithme est utilisé et comment il fonctionne. Le concept clé du hachage cohérent est que, bien que les fonctions de hachage puissent accepter tout type d'entrée, leur sortie est limitée à un seul entier non signé (entiers de 32, 64 ou 128 bits selon la fonction de hachage). Cela nous permet de relier les tâches et les serveurs les uns aux autres de manière cohérente. La plupart des discussions sur le hachage cohérent vous font imaginer cet espace de sortie comme un anneau continu et circulaire qui revient de sa valeur maximale à zéro. Cette représentation permet de belles visualisations, mais elle peut aussi rendre le concept simple de plages d'entiers plus compliqué qu'il ne devrait l'être. Pour notre discussion, nous représenterons la sortie 32 bits de notre fonction de hachage comme une droite numérique. Maintenant, disons que nous avons un ensemble de serveurs, A, B et C, et un ensemble de tâches t-z. Nous pouvons mapper chacun sur la droite numérique en fonction du hachage de leurs valeurs représentatives, comme les adresses IP pour les serveurs et les clés de cache pour les tâches. Attribuer des tâches aux serveurs n'est plus qu'une question de trouver le premier serveur à gauche de chaque tâche. Nous pouvons représenter cela visuellement en colorant la région des hachages qui sera associée à chaque serveur. Notez que la plage couverte par le serveur C revient au début, d'où l'idée que les hachages existent dans un anneau. Et c'est tout. À un niveau de base, le hachage cohérent est aussi simple que cela — mais il ne faut pas longtemps pour voir qu'il y a place à l'amélioration. Notez que la plage couverte par le serveur A dans notre exemple est nettement plus grande que celle de B ou C. C'est un problème car la fraction des requêtes qu'un serveur traite sera proportionnelle à la taille de sa plage sur la droite numérique. Idéalement, nous voudrions garantir que chaque serveur ait une taille égale, mais comme les hachages sont essentiellement des nombres aléatoires, nous devons...