Assurer la fiabilité des plateformes à grande échelle

L'exploitation d'une plateforme distribuée évolutive exige un engagement en matière de fiabilité, afin de garantir que les clients disposent de ce dont ils ont besoin quand ils en ont besoin. Les dépendances peuvent être assez complexes, en particulier avec une plateforme aussi vaste que Roblox. Construire des services fiables signifie que, quelle que soit la complexité et l'état des dépendances, un service donné ne sera pas interrompu (c'est-à-dire hautement disponible), fonctionnera sans bug (c'est-à-dire de haute qualité) et sans erreur (c'est-à-dire tolérant aux pannes).
Pourquoi la fiabilité est-elle importante ?
Notre équipe chargée de l'identité des comptes s'engage à atteindre un niveau de fiabilité plus élevé, car les services de conformité que nous avons développés constituent des composants essentiels de la plateforme. Une défaillance de la conformité peut avoir de graves conséquences. Le coût lié au blocage du fonctionnement normal de Roblox est très élevé, car il nécessite des ressources supplémentaires pour la reprise après une panne et entraîne une dégradation de l'expérience utilisateur.
L'approche classique de la fiabilité se concentre principalement sur la disponibilité, mais dans certains cas, les termes sont confondus et mal utilisés. La plupart des mesures de disponibilité se contentent d'évaluer si les services sont opérationnels, tandis que des aspects tels que la tolérance aux partitions et la cohérence sont parfois oubliés ou mal compris.
Conformément au théorème CAP, tout système distribué ne peut garantir que deux de ces trois aspects ; nos services de conformité sacrifient donc une partie de la cohérence afin d'être hautement disponibles et tolérants aux partitions. Néanmoins, nos services n'ont fait que de faibles concessions et ont trouvé des mécanismes pour atteindre une bonne cohérence grâce à des modifications architecturales raisonnables, expliquées ci-dessous.
Le processus visant à atteindre une fiabilité accrue est itératif, avec des mesures rigoureuses s'accompagnant d'un travail continu afin de prévenir, identifier, détecter et corriger les défauts avant que des incidents ne se produisent. Notre équipe a identifié une forte valeur dans les pratiques suivantes :
- Mesure adéquate - Mettre en place une observabilité complète sur la manière dont la qualité est fournie aux clients et dont les dépendances nous fournissent de la qualité.
- Anticipation proactive - Mener des activités telles que des revues d'architecture et des évaluations des risques liés aux dépendances.
- Priorité à la correction - Accorder une attention accrue à la résolution des rapports d'incident pour le service et les dépendances liées à notre service.
Le renforcement de la fiabilité exige une culture de la qualité. Notre équipe investissait déjà dans le développement axé sur la performance et sait que le succès d'un processus dépend de son adoption. L'équipe a adopté ce processus dans son intégralité et a appliqué ces pratiques comme norme. Le diagramme suivant met en évidence les composantes du processus :

L'importance d'une mesure adéquate
Avant d'approfondir le sujet des indicateurs, il convient d'apporter une petite précision concernant les mesures du niveau de service.
- Le SLO (objectif de niveau de service) est l'objectif de fiabilité que notre équipe vise (par exemple, 99,999 %).
- Le SLI (indicateur de niveau de service) correspond à la fiabilité atteinte sur une période donnée (par exemple, 99,975 % en février dernier).
- Le SLA (accord de niveau de service) est le niveau de fiabilité convenu et attendu par nos clients sur une période donnée (par exemple, 99,99 % par semaine).
Le SLI doit refléter la disponibilité (aucune réponse non traitée ou manquante), la tolérance aux pannes (aucune erreur de service) et la qualité atteinte (aucune erreur inattendue). Par conséquent, nous avons défini notre SLI comme le « taux de réussite » des réponses réussies par rapport au total des requêtes envoyées à un service. Les réponses réussies sont les requêtes qui ont été traitées dans les délais et sous la forme attendue, c'est-à-dire sans erreur de connectivité, de service ou erreur inattendue.
Cet indicateur de performance clé (SLI) ou taux de réussite est collecté du point de vue des consommateurs (c'est-à-dire des clients). L'objectif est de mesurer l'expérience de bout en bout réelle offerte à nos consommateurs afin d'avoir l'assurance que les SLA sont respectés. Ne pas le faire créerait un faux sentiment de fiabilité qui ignorerait toutes les préoccupations liées à l'infrastructure nécessaire pour se connecter à nos clients. À l'instar de l'indicateur de performance clé (SLI) des consommateurs, nous collectons l'indicateur de performance clé (SLI) des dépendances afin de suivre tout risque potentiel. En pratique, tous les SLA de dépendance doivent s’aligner sur le SLA de service et il existe une dépendance directe avec celui-ci. La défaillance de l’un implique la défaillance de tous. Nous suivons et rapportons également les métriques provenant du service lui-même (c’est-à-dire le serveur), mais cela ne constitue pas la source pratique d’une haute fiabilité.
En plus des SLI, chaque build collecte des métriques de qualité qui sont rapportées par notre workflow CI. Cette pratique permet de renforcer considérablement les contrôles de qualité (c'est-à-dire la couverture de code) et de rapporter d'autres métriques pertinentes, telles que la conformité aux normes de codage et l'analyse statique du code. Ce sujet a déjà été abordé dans un autre article, « Building Microservices Driven by Performance ». Le respect rigoureux de la qualité est déterminant en matière de fiabilité, car plus nous investissons pour atteindre d'excellents scores, plus nous sommes confiants que le système ne tombera pas en panne dans des conditions défavorables.
Notre équipe dispose de deux tableaux de bord. L'un offre une visibilité complète sur les SLI des consommateurs et des dépendances. Le second affiche toutes les métriques de qualité. Nous travaillons à la fusion de l'ensemble dans un tableau de bord unique, afin que tous les aspects qui nous importent soient regroupés et prêts à être rapportés pour n'importe quelle période donnée.
Anticiper les défaillances
La réalisation de revues d'architecture est un élément fondamental de la fiabilité. Tout d'abord, nous déterminons si une redondance est en place et si le service dispose des moyens de survivre en cas de défaillance des dépendances. Au-delà des concepts classiques de réplication, la plupart de nos services ont mis en œuvre des techniques améliorées de double hydratation du cache, des stratégies de double récupération (telles que les files d'attente locales de basculement) ou des stratégies de gestion de la perte de données (telles que la prise en charge des transactions). Ces sujets sont suffisamment vastes pour mériter un autre article de blog, mais en fin de compte, la meilleure recommandation est de mettre en œuvre des solutions qui prennent en compte les scénarios de catastrophe et minimisent toute perte de performance.
Un autre aspect important à anticiper concerne tout ce qui pourrait améliorer la connectivité. Cela implique d’être proactif en matière de faible latence pour les clients et de les préparer à un trafic très élevé à l’aide de techniques de contrôle du cache, de sidecars et de politiques performantes pour les délais d’expiration, les disjoncteurs de circuit et les tentatives de reconnexion. Ces pratiques s'appliquent à tous les clients, y compris les caches, les magasins, les files d'attente et les clients interdépendants en HTTP et gRPC. Cela implique également d'améliorer les signaux de bon fonctionnement émis par les services et de comprendre que les contrôles de santé jouent un rôle important dans toute orchestration de conteneurs. La plupart de nos services émettent de meilleurs signaux de dégradation dans le cadre du retour d'information des contrôles de santé et vérifient que tous les composants critiques sont fonctionnels avant d'envoyer des signaux de bon fonctionnement.
La division des services en éléments critiques et non critiques s'est avérée utile pour se concentrer sur les fonctionnalités qui comptent le plus. Nous avions auparavant des points de terminaison réservés à l'administration au sein du même service, et bien qu'ils ne fussent pas souvent utilisés, ils affectaient les métriques de latence globales. Leur transfert vers leur propre service a eu un impact positif sur toutes les métriques.
L'évaluation des risques liés aux dépendances est un outil important pour identifier les problèmes potentiels avec les dépendances. Cela signifie que nous identifions les dépendances présentant un faible SLI et demandons un alignement sur le SLA. Ces dépendances nécessitent une attention particulière lors des étapes d'intégration ; nous consacrons donc du temps supplémentaire à l'analyse comparative et aux tests pour vérifier si les nouvelles dépendances sont suffisamment matures pour nos projets. Un bon exemple est l'adoption précoce que nous avons faite du service de stockage en tant que service (Storage-as-a-Service) de Roblox. L'intégration de ce service a nécessité la création de tickets de bug et des réunions de synchronisation périodiques pour communiquer les conclusions et les retours d'expérience. Tout ce travail est associé au tag « fiabilité » afin que nous puissions rapidement identifier sa source et ses priorités. La caractérisation a été répétée jusqu'à ce que nous ayons la certitude que la nouvelle dépendance était prête à l'emploi. Ce travail supplémentaire a permis d'amener la dépendance au niveau de fiabilité requis que nous nous attendons à fournir en agissant ensemble vers un objectif commun.
Mettre de l'ordre dans le chaos
Il n’est jamais souhaitable d’avoir des incidents. Mais lorsqu’ils se produisent, il y a des informations utiles à recueillir et dont il faut tirer des leçons afin d’être plus fiables. Notre équipe dispose d’un rapport d’incidents propre à l’équipe, qui va au-delà du rapport habituel à l’échelle de l’entreprise, ce qui nous permet de nous concentrer sur tous les incidents, quelle que soit l’ampleur de leur impact. Nous identifions la cause profonde et hiérarchisons toutes les tâches pour l'atténuer à l'avenir. Dans le cadre de ce rapport, nous faisons appel à d'autres équipes pour résoudre les incidents de dépendance hautement prioritaires, assurons le suivi avec une résolution adéquate, procédons à une rétrospective et recherchons des schémas qui pourraient s'appliquer à nous.
L'équipe produit un rapport mensuel de fiabilité par service qui inclut tous les indicateurs de performance clés (SLI) expliqués ici, tous les tickets que nous avons ouverts pour des raisons de fiabilité et tous les incidents éventuels associés au service. Nous sommes tellement habitués à générer ces rapports que la prochaine étape logique consiste à automatiser leur extraction. Il est important de mener cette activité périodique, car elle nous rappelle que la fiabilité est constamment suivie et prise en compte dans notre développement.

Nos outils comprennent des indicateurs personnalisés et des alertes améliorées afin que nous soyons avertis dès que possible lorsque des problèmes connus ou attendus surviennent. Toutes les alertes, y compris les faux positifs, sont examinées chaque semaine. À ce stade, il est important de peaufiner toute la documentation afin que nos utilisateurs sachent à quoi s'attendre lorsque des alertes se déclenchent et que des erreurs surviennent, et que chacun sache alors quoi faire (par exemple, les guides d'intervention et les directives d'intégration sont harmonisés et mis à jour régulièrement).
En fin de compte, l'intégration de la qualité dans notre culture est le facteur le plus critique et décisif pour atteindre une fiabilité supérieure. Nous pouvons constater que ces pratiques, appliquées à notre travail quotidien, portent déjà leurs fruits. Notre équipe est obsédée par la fiabilité, et c’est notre plus grande réussite. Nous avons pris davantage conscience de l’impact que des défauts potentiels pourraient avoir et du moment où ils pourraient se produire. Les services qui ont mis en œuvre ces pratiques ont systématiquement atteint leurs SLO et leurs SLA. Les rapports de fiabilité qui nous aident à suivre tout le travail que nous avons accompli témoignent du travail réalisé par notre équipe et constituent des leçons inestimables pour informer et influencer d’autres équipes. C’est ainsi que la culture de la fiabilité touche tous les composants de notre plateforme.
Le chemin vers une plus grande fiabilité n’est pas facile, mais il est nécessaire si l’on souhaite construire une plateforme de confiance qui réinvente la manière dont les gens se rassemblent.
Alberto est ingénieur logiciel principal au sein de l'équipe Account Identity chez Roblox. Il travaille depuis longtemps dans l'industrie du jeu vidéo et a participé à de nombreux titres de jeux AAA et plateformes de réseaux sociaux, en mettant l'accent sur les architectures hautement évolutives. Il aide aujourd'hui Roblox à atteindre la croissance et la maturité en appliquant les meilleures pratiques de développement.


