Pourquoi Slack est passé à l'architecture cellulaire
Publié par Clément Bohic le | Mis à jour le
Pour gagner en disponibilité sur une région AWS, Slack a réarchitecturé ses principaux services en cellules.
En cas de défaillance d'une zone de disponibilité, comment détourner rapidement le trafic réseau sans engendrer d'impact perceptible sur les utilisateurs finaux ? Pour Slack, la réponse a résidé dans une architecture cellulaire.
Il a fallu un an et demi à l'éditeur américain pour appliquer cette approche aux plus critiques de ses services. À l'origine, il y a un incident survenu en juin 2021 chez son principal fournisseur cloud (AWS). En l'occurrence, des pannes intermittentes sur un lien réseau physique, d'abord rétabli puis finalement décommissionné après avoir à nouveau dysfonctionné à quelques heures d'intervalle.
Bien que limité à une zone de disponibilité, le problème avait entraîné une dégradation de service chez les utilisateurs. D'après Slack, cela tenait à la façon dont le système s'est perçu lui-même : ses composantes n'avaient pas toutes les mêmes informations de disponibilité. Ce jusqu'au sein d'une même zone : deux clients pouvaient avoir une vue différente des back-end de la zone impactée selon que leurs flux réseau y transitaient ou non.
Dans ce contexte, Slack a opté pour une architecture en cellules, chacune correspondant à une zone de disponiblité. Il s'agissait de développer une forme de « bouton d'urgence » permettant de rediriger le trafic en cas de souci. Il s'agissait que cette action :
> Agisse sur autant de trafic que possible dans un délai de 5 minutes (en toile de fond, le SLA à 99,99 % des forfaits Business Plus, Enterprise et GovGrid, qui garantit moins d'une heure d'indisponibilité par an)
> Ne se traduise pas par des erreurs visibles par les utilisateurs
> Soit incrémentale (capacité à restaurer très peu de trafic, à des fins de contrôle)
> Ne dépende pas de ressources localisées dans la zone de disponibilité
Un socle Envoy / xDS
Une implémentation basique respectant ces objectifs aurait pu impliquer l'intégration d'un signal dans chaque client RPC. Problème : cela aurait nécessité une implémentation dans chacun des langages sur lesquels repose l'édifice Slack : Hack, Go, Java et C++. Il aurait par ailleurs fallu composer avec DNS, qui ne propose pas d'abstraction pour des éléments tels que les zones de disponibilité. Ainsi qu'avec des systèmes open source comme le datastore Vitess, au risque de devoir gérer un fork.
Slack s'est donc rabattu sur une mise en silo. Dans ce schéma, les services ne communiquent qu'au sein de leur zone de disponibilité. La défaillance est donc circonscrite à ce périmètre. Et on peut gérer la redirection du trafic au niveau du front. Rotor, le plan de contrôle xDS maison, envoie un signal aux équilibreurs de charge en périphérie du réseau, qui exploitent la fonction weighted_clusters du proxy Envoy.
La propagation à travers le plan de contrôle est une affaire de secondes et la fonction weighted_clusters offre une granularité répondant à l'objectif de restauration incrémentale du trafic. En termes de résilience, les équilibreurs de charge se trouvent dans des régions différentes et le plan de contrôle est répliqué sur plusieurs zones.
AWS, fournisseur de Slack, a son modèle de déploiement
Comment les données sont-elles répliquées entre les instances des services ? Qu'en est-il de ceux qu'on ne peut mettre en silo ? Slack n'aborde pas ces deux points.
Son fournisseur AWS a lui-même mis en place une architecture de type cellulaire, en complément à la technique du partitionnement aléatoire (shuffle sharding). Il propose d'ailleurs un modèle de déploiement.
La maison mère Amazon a également fait le pas, par exemple pour sa filiale de robotique (ex-Kiva Systems). Cette dernière a placé chaque cellule - correspondant à un entrepôt - dans un compte AWS. Un compte supplémentaire centralise logs et traces (cf. vidéo ci-dessous à partir de 16'32 »).
Facebook et Salesforce font partie des entreprises à avoir adopté, bien plus en amont, une forme d'architecture en cellules. Le premier l'a fait pour sa messagerie, en alliant le serveur d'application, un magasin de métadonnées et des contrôleurs ZooKeeper. Le second a fédéré serveurs Java et Oracle RAC.
Illustration principale © alejomiranda - Adobe Stock