Disparités de charge de Cassandra avec les lectures de quorum basées sur le WAN
Chez PagerDuty, nous sommes confrontés à des défis architecturaux intéressants afin de garantir la diffusion des alertes et de fournir à nos clients le plus haut niveau de fiabilité possible. Nous avons déclaré dans le passé que si vous recevez un 200 d'accord
à partir du point de terminaison de l'événement PagerDuty , vous volonté être paginé… même si le centre de données avec lequel vous avez communiqué disparaît immédiatement après votre demande. Afin de conserver cette garantie, nous devons écrire l'événement de manière synchrone dans plusieurs centres de données. Nous utilisons Apache Cassandra pour y parvenir et, par conséquent, s’appuient fortement sur la majorité quorum lit et écrit.
Avec de telles garanties en place, nous avons des exigences inhabituelles pour nos déploiements Cassandra. Un déploiement Cassandra typique chez PagerDuty se compose de cinq nœuds répartis sur trois centres de données, avec un facteur de réplication de cinq. Cette configuration fonctionne bien pour les lectures et écritures de quorum géo-distribuées hautement disponibles, et nous avons j'en ai déjà parlé , même si nous ne sommes pas ici pour en parler aujourd'hui. Au lieu de cela, nous allons discuter de quelque chose d'un peu plus intéressant : les points chauds de lecture déterministes, malgré une distribution de données parfaitement uniforme et des modèles d'accès uniformes !
Ces boîtes chauffent tout simplement…
Nous avons remarqué depuis un certain temps que les hôtes Cassandra dans l'un de nos centres de données (AWS us-west-1) chauffent plus que les autres. Nous nous sommes également rendu compte que le matériel de ce centre de données était légèrement plus ancien et moins efficace que celui des deux autres. Cela semblait assez simple : le matériel plus faible de ce centre de données entraînait une charge élevée par rapport au matériel quelque peu meilleur du reste de l'anneau. L'un des hôtes de l'anneau a plus de cœurs que les autres (situé dans Linode) et est donc le moins chargé, ce qui renforce l'hypothèse du matériel. Voici un graphique de la charge sur 5 minutes sur tous les hôtes de l'un de nos anneaux Cassandra :
Vous pouvez voir clairement la case « la plus forte » en bas avec la charge la plus faible, les hôtes us-west-1 « faibles » en haut et les hôtes us-west-2 moins faibles au milieu. Le rasoir d'Occam , non ? Pas si vite.
Plus de données, plus de visibilité
Avec l'hypothèse d'un matériel sain et solide en place, nous nous sommes sentis à l'aise et n'avons pas vu la nécessité d'enquêter davantage. Un certain temps a passé, nous avons grandi, et notre charge Cassandra aussi. Il était temps de commencer à optimiser nos opérations Cassandra. La première chose requise pour régler correctement un cluster Cassandra est, bien sûr, PLUS DE DONNÉES !
Une mise à niveau de Cassandra nous a fourni plus de mesures que nous ne savions quoi en faire. Nous avons commencé à créer de nouveaux tableaux de bord pour voir si nous pouvions trouver quelque chose d'intéressant. Il y a eu plusieurs surprises, mais l'une d'entre elles en particulier défiait toute explication : alors que les écritures étaient réparties de manière uniforme sur tous les nœuds, la charge de lecture était asymétrique. Une enquête plus approfondie a montré que ce modèle était présent dans plusieurs services différents avec une topologie similaire.
Trois hôtes recevaient systématiquement plus de lectures que les deux autres. C'était surprenant, car la charge de lecture entrant dans le système était symétrique et, avec un facteur de réplication égal à la taille du cluster, tout devrait être égal. En examinant la topologie, il est devenu évident que les hôtes les plus chargés se trouvaient tous dans us-west-1 et Linode. En excluant Linode comme une valeur aberrante (en raison du nombre plus élevé de cœurs de processeur), il était clair que l'hypothèse matérielle était incorrecte : ces nœuds chauds étaient en effet plus occupés que les autres.
Opérations de lecture et d'écriture de Cassandra
Nous effectuons des écritures de quorum, mais en raison de notre facteur de réplication élevé, tous les nœuds doivent écrire les données. coordinateur il suffit d'un accusé de réception majoritaire pour réussir, l'écriture est quand même envoyée à tout le monde. Nous effectuons également des lectures de quorum, mais contrairement aux écritures, la lecture n'est envoyée qu'au nombre minimum de nœuds requis. Dans notre cas, ce nombre est de trois... très suspect.
Le coordinateur est responsable de la sélection des nœuds à partir desquels il souhaite lire. Il s'avère qu'il sélectionne les nœuds qui ont été répondre le plus rapidement Certes, le matériel légèrement plus lent n'est pas plus performant, alors qu'est-ce qui se passe ?
RTT est une chose
Étant donné que nos clusters Cassandra sont répartis géographiquement, la communication entre les nœuds prend un peu de temps. La durée exacte est déterminée par la source et la destination, car les relations ne sont pas équilatérales. Voici un diagramme illustrant notre topologie et les latences aller-retour approximatives entre elles :
Si nous partons du principe que tous les membres ont les mêmes performances en termes de latence de lecture, nous pouvons commencer à calculer la probabilité qu'un nœud particulier reçoive une demande de lecture d'un coordinateur donné. Ainsi, pour chaque nœud de l'anneau, nous trouvons les voisins les plus proches (et donc les réponses les plus rapides). À l'aide d'étiquettes [AE]
comme indiqué dans le diagramme précédent, nous pouvons générer un tableau :
Coordinateur | Voisins | Un problème. | Problème B. | C problème | D problème | Et problème |
---|---|---|---|---|---|---|
UN | A, B, C | 1 | 1 | 1 | 0 | 0 |
B | A, B, C | 1 | 1 | 1 | 0 | 0 |
C | A, B, C | 1 | 1 | 1 | 0 | 0 |
D | D, E, (A, B, C) | .33 | .33 | .33 | 1 | 1 |
E | D, E, (A, B, C) | .33 | .33 | .33 | 1 | 1 |
Avec ce tableau en main, nous pouvons voir que les nœuds DE recevront une lecture seulement 2/5 du temps, ce qui signifie que les nœuds AC finissent par recevoir environ 60 % de lectures de plus que leurs homologues !
Distribution de lecture dans le monde réel
En pratique, nous ne sommes pas si loin de la vérité. En observant le graphique des opérations de lecture, les nœuds us-west-2 effectuent en moyenne 75 lectures/s, tandis que les autres enregistrent environ 115 à 120 lectures/s, soit une augmentation surprenante de 60 % ! Nous observons un léger décalage à mesure que les routes augmentent et que les latences de lecture locales changent, mais même avec ces variables en jeu, nous restons remarquablement proches des prédictions faites par le tableau de distribution.
Enseignements et points à retenir
Maintenant que nous avons compris tout cela, la question naturelle à se poser est : « Et bien, que pouvons-nous faire à ce sujet ? » Déplacer les centres de données de manière à ce qu'ils soient à égale distance les uns des autres en termes de réseau serait une tentative futile, car les routes Internet peuvent facilement changer. Distribuer nos lectures de manière inégale pour nous appuyer davantage sur les nœuds DE en tant que coordinateurs entraînerait une pénalité de performance inutile, car les clients des autres centres de données devraient traverser une route Internet pour atteindre le cluster. Hélas, il semble que la réponse la plus appropriée soit simplement de faire évoluer les nœuds AC et d'absorber la charge. Cela peut être problématique si nous devions perdre un centre de données, mais c'est gérable tant que les restes ne sont pas sous-provisionnés pour un tel cas.
Ce fut un apprentissage très intéressant pour nous. La réponse semble désormais évidente, mais elle sert d'exemple de la facilité avec laquelle on peut formuler des hypothèses sur nos systèmes qui ne tiennent tout simplement pas dans la vie réelle. Il convient également de noter que ce n'est pas un comportement spécifique à Cassandra . Tout système distribué géographiquement qui envoie du travail aux hôtes ayant le temps de réponse le plus court souffrira de ce phénomène. Un point à garder à l'esprit si jamais vous vous retrouvez à construire un système avec des caractéristiques similaires… nous espérons vous avoir fait gagner du temps :).
Un grand merci à tous les ingénieurs de PagerDuty qui ont pris le temps de résoudre ce problème. Sans eux, ce billet de blog n'aurait pas été possible ! N'oubliez pas de consulter nos conférences du Cassandra Summit sur ce sujet et bien d'autres, par Donny Nadolny et Paul Rechsteiner .