Comment Grab a optimisé ses coûts Kafka sur AWS

Grab Kafka

Grab a modifié l’architecture de son cluster Kafka pour réduire le volume de trafic entre zones de disponibilité AWS.

Que se passe-t-il quand les frais de réseau en arrivent à représenter la moitié du coût d’un déploiement Kafka ? Confronté à cette situation, Grab a entrepris de  alors entreprise de modifier l’architecture de son cluster.

La configuration initiale, dans les grandes lignes :

– Hébergement dans une région AWS, sur trois AZ où s’exécutent brokers et clients
– Trois réplicas pour chaque partition Kafka
– Des clusters rack-aware, de sorte que chaque réplica réside dans une zone de disponibilité différente

Problème avec cette architecture : elle générait beaucoup de trafic entre AZ. La raison : par défaut, les clients Kafka ne communiquaient qu’avec le leader de la partition. Lequel a deux chances sur trois de se trouver dans une autre AZ.

Le trafic en question intervient sur trois plans :

> Lorsqu’un producteur se trouve dans une autre AZ que le leader de la partition vers laquelle il envoie les données
> Lors de la réplication des données ingérées du leader vers les followers, qui se trouvent dans les deux autres AZ
> Quand les consommateurs ne se trouvent pas dans la même AZ que le leader

Les deux premiers postes entraînent une augmentation minimale des échanges cross-AZ. C’est le troisième qui pose problème : il peut, en théorie, y avoir autant de trafic qu’il y a de consommateurs.

Un trafic cross-AZ réduit de 25 %…

La solution a impliqué, entre autres, la mise à jour de Kafka. Objectif : exploiter une fonctionnalité introduite avec la version 2.3 : la possibilité, pour les consommateurs, de s’alimenter depuis des réplicas. Grab pouvait alors faire en sorte que ces échanges aient lieu au sein de la même AZ.

La décision a été prise de migrer directement vers Kafka 3.1, alors stable depuis plus d’un an. Première étape : mettre à jour Zookeeper, en assurant une rétrocompatibilité avec l’ancienne version de Kafka. Ensuite, on déploie l’upgrade de Kafka, en paramétrant une version de protocole inter-brokers explicitement rétrocompatible (objectif : gérer l’hétérogénéité temporaire du cluster pendant la migration). À ce stade, on upgrade aussi Cruise Control. Dernière étape : aligner tous les brokers sur une version récente dudit protocole.

La démarche a supposé des évolutions de configuration. Côté brokers, Grab avait déjà enclenché le paramètre broker.rack pour distribuer les réplicas. Son rôle Ansible le peuplait automatiquement avec les identifiants d’AZ, récupérées dans les métadonnées EC2 au moment du déploiement. Identifiants plutôt que noms, précise l’entreprise, parce que le mapping des seconds n’est pas cohérent entre comptes AWS.
Pour l’activation côté serveur, il a fallu ajouter le paramètre replica.selector.class, avec la valeur org.apache.kafka.common.replica.RackAwareReplicaSelector.

L’essentiel des consommateurs s’appuyant sur un SDK interne, celui-ci a été mis à jour afin de supporter la récupération depuis le réplica le plus proche. Pour activer cette fonctionnalité, les utilisateurs doivent exporter une variable d’environnement. Sur un principe similaire à celui côté brokers, le SDK peuple le paramètre client.rack. Grab a implémenté la même logique pour les flux ne passant pas par le SDK. En l’occurrence, pipelines Flink et connecteurs Kafka Connect.

En maintenant une consommation stable, le volume de trafic cross-AZ a diminué de 25 % en trois mois. Une baisse à considérer sous deux angles, au vu des règles de facturation d’AWS : trafic sortant pour les brokers, trafic entrant pour les clients.

… en contrepartie de régressions

Contrepartie à ce changement d’architecture, la latence de bout en bout a augmenté (jusqu’à 500 ms en plus). C’était attendu, mais pas acceptable sur certains cas d’usage… pour lesquels Grab a conservé son design d’origine.

Une autre contrariété a émergé sur l’isolation des brokers. Dans l’architecture initiale, les clients Kafka ne communiquaient qu’avec les leaders. Rétrograder un broker pour la maintenance revenait à l’isoler de tous les clients.
En pointant vers le réplica le plus proche, les consommateurs maintiennent le lien avec le broker rétrogradé, puisque celui-ci continue à servir les followers. Il faut donc implémenter une gestion des erreurs, sans quoi les consommateurs se retrouvent déconnectés.

Le niveau de charge sur les brokers est un autre écueil. Il dépend directement de l’emplacement des consommateurs. Si ces derniers ne se répartissent par équitablement entre les trois AZ, alors la charge en question se retrouve déséquilibrée de la même manière.
Ajouter des brokers peut aider à supporter la charge, mais cela entraîne un coût. En parallèle, il n’est pas souhaitable d’en supprimer dans les AZ moins chargées, étant donné que des consommateurs peuvent s’y relocaliser à tout moment.

Illustration © Danloe – Adobe Stock