Le contenu de ce site a été traduit à l'aide de l'intelligence artificielle (IA) ou d'une technologie de traduction automatique, et peut contenir des erreurs.

Skip to content

Comment nous rendons l'infrastructure de Roblox plus efficace et plus résiliente

Au fur et à mesure que Roblox s'est développé au cours des 16 dernières années, l'infrastructure technique qui prend en charge des millions d'expériences collaboratives immersives en 3D a également gagné en ampleur et en complexité. Le nombre de machines que nous gérons a plus que triplé au cours des deux dernières années, passant d'environ 36 000 au 30 juin 2021 à près de 145 000 aujourd'hui. La prise en charge de ces expériences disponibles en permanence pour des utilisateurs du monde entier nécessite plus de 1 000 services internes. Afin de maîtriser les coûts et la latence du réseau, nous déployons et gérons ces machines au sein d’une infrastructure de cloud privé hybride et sur mesure, fonctionnant principalement sur site.  

Notre infrastructure prend actuellement en charge plus de 70 millions d’utilisateurs actifs quotidiens à travers le monde, y compris les créateurs qui comptent sur l’économie de Roblox pour leurs activités. Tous ces millions de personnes attendent un niveau de fiabilité très élevé. Compte tenu de la nature immersive de nos expériences, la tolérance aux décalages ou à la latence est extrêmement faible, sans parler des pannes. Roblox est une plateforme de communication et de connexion, où les gens se réunissent dans des expériences 3D immersives. Lorsque les gens communiquent via leurs avatars dans un espace immersif, même les retards ou les dysfonctionnements mineurs sont plus perceptibles que sur un fil de discussion ou lors d’une visioconférence.

En octobre 2021, nous avons subi une panne à l’échelle du système. Elle a commencé modestement, par un problème sur un composant dans un centre de données. Mais elle s’est rapidement propagée pendant que nous menions notre enquête et a finalement entraîné une panne de 73 heures. À l’époque, nous avons partagé à la fois les détails de ce qui s’était passé et certains des premiers enseignements tirés de cet incident. Depuis lors, nous avons étudié ces enseignements et travaillé à renforcer la résilience de notre infrastructure face aux types de défaillances qui surviennent dans tous les systèmes à grande échelle en raison de facteurs tels que les pics de trafic extrêmes, les conditions météorologiques, les pannes matérielles, les bogues logiciels ou simplement les erreurs humaines. Lorsque ces défaillances se produisent, comment nous assurons-nous qu’un problème affectant un seul composant, ou un groupe de composants, ne se propage pas à l’ensemble du système ? Cette question a été au cœur de nos préoccupations ces deux dernières années et, bien que le travail soit toujours en cours, ce que nous avons accompli jusqu’à présent porte déjà ses fruits. Par exemple, au cours du premier semestre 2023, nous avons économisé 125 millions d’heures d’engagement par mois par rapport au premier semestre 2022. Aujourd’hui, nous partageons le travail que nous avons déjà accompli, ainsi que notre vision à plus long terme pour la construction d’un système d’infrastructure plus résilient.

Mise en place d'un filet de sécurité

Au sein des systèmes d'infrastructure à grande échelle, des pannes à petite échelle se produisent plusieurs fois par jour. Si une machine rencontre un problème et doit être mise hors service, cela reste gérable car la plupart des entreprises disposent de plusieurs instances de leurs services back-end. Ainsi, lorsqu'une instance tombe en panne, les autres prennent le relais. Pour faire face à ces pannes fréquentes, les requêtes sont généralement configurées pour réessayer automatiquement en cas d'erreur.

Cela devient problématique lorsqu'un système ou une personne effectue des tentatives de réessai de manière trop agressive, ce qui peut entraîner la propagation de ces pannes à petite échelle à travers l'infrastructure vers d'autres services et systèmes. Si le réseau ou un utilisateur effectue des tentatives de réessai de manière suffisamment persistante, cela finira par surcharger toutes les instances de ce service, et potentiellement d'autres systèmes, à l'échelle globale. Notre panne de 2021 était le résultat d’un phénomène assez courant dans les systèmes à grande échelle : une défaillance commence modestement puis se propage à travers le système, prenant rapidement une ampleur telle qu’il est difficile de la résoudre avant que tout ne tombe en panne. 

Au moment de notre panne, nous disposions d’un seul centre de données actif (dont les composants servaient de sauvegarde). Nous avions besoin de pouvoir basculer manuellement vers un nouveau centre de données lorsqu’un problème mettait le centre existant hors service. Notre priorité absolue était de nous assurer de disposer d’un déploiement de secours de Roblox ; nous avons donc mis en place cette solution de secours dans un nouveau centre de données, situé dans une autre région géographique. Cela a renforcé notre protection face au pire scénario : une panne se propageant à suffisamment de composants au sein d’un centre de données pour le rendre totalement inopérant. Nous disposons désormais d’un centre de données traitant les charges de travail (actif) et d’un autre en veille, servant de secours (passif). Notre objectif à long terme est de passer de cette configuration active-passive à une configuration active-active, dans laquelle les deux centres de données gèrent les charges de travail, avec un équilibreur de charge répartissant les requêtes entre eux en fonction de la latence, de la capacité et de l'état de santé. Une fois ce système en place, nous espérons bénéficier d'une fiabilité encore plus élevée pour l'ensemble de Roblox et être en mesure d'effectuer une bascule de secours presque instantanément, plutôt que sur plusieurs heures.

Passage à une infrastructure cellulaire

Notre priorité suivante était de créer des murs anti-explosion solides à l'intérieur de chaque centre de données afin de réduire le risque de défaillance totale d'un centre de données. Les cellules (que certaines entreprises appellent des clusters) sont essentiellement un ensemble de machines et constituent le moyen par lequel nous créons ces murs. Nous répliquons les services à la fois au sein des cellules et entre elles pour une redondance accrue. À terme, nous souhaitons que tous les services de Roblox fonctionnent dans des cellules afin qu'ils puissent bénéficier à la fois de murs anti-explosion solides et de redondance. Si une cellule n'est plus fonctionnelle, elle peut être désactivée en toute sécurité. La réplication entre les cellules permet au service de continuer à fonctionner pendant la réparation de la cellule. Dans certains cas, la réparation d'une cellule peut impliquer un provisionnement complet de celle-ci. Dans l'ensemble du secteur, l'effacement et le provisionnement d'une machine individuelle ou d'un petit ensemble de machines sont assez courants, mais cela ne l'est pas pour une cellule entière, qui contient environ 1 400 machines. 

Pour que cela fonctionne, ces cellules doivent être largement uniformes, afin que nous puissions déplacer rapidement et efficacement les charges de travail d’une cellule à l’autre. Nous avons défini certaines exigences auxquelles les services doivent satisfaire avant de s’exécuter dans une cellule. Par exemple, les services doivent être conteneurisés, ce qui les rend beaucoup plus portables et empêche quiconque d’apporter des modifications de configuration au niveau du système d’exploitation. Nous avons adopté une philosophie d’« infrastructure as code » pour les cellules : dans notre référentiel de code source, nous incluons la définition de tout ce qui se trouve dans une cellule afin de pouvoir la reconstruire rapidement à partir de zéro à l’aide d’outils automatisés. 

Tous les services ne répondent pas encore à ces exigences ; nous avons donc aidé les responsables de services à s’y conformer dans la mesure du possible, et nous avons développé de nouveaux outils pour faciliter la migration des services vers les cellules lorsqu’ils sont prêts. Par exemple, notre nouvel outil de déploiement « répartit » automatiquement le déploiement d’un service entre les cellules, de sorte que les propriétaires de services n’ont pas à se soucier de la stratégie de réplication. Ce niveau de rigueur rend le processus de migration beaucoup plus difficile et chronophage, mais le bénéfice à long terme sera un système où : 

  • Il est beaucoup plus facile de contenir une défaillance et d'empêcher qu'elle ne se propage à d'autres cellules ; 
  • Nos ingénieurs d'infrastructure peuvent être plus efficaces et agir plus rapidement ; et 
  • Les ingénieurs qui développent les services au niveau des produits, qui sont finalement déployés dans des cellules, n’ont pas besoin de savoir ni de se soucier des cellules dans lesquelles leurs services s’exécutent.

Relever des défis plus importants

À l'instar des portes coupe-feu utilisées pour contenir les flammes, les cellules agissent comme de solides murs anti-explosion au sein de notre infrastructure afin de contenir tout problème à l'origine d'une défaillance au sein d'une seule cellule. À terme, tous les services qui composent Roblox seront déployés de manière redondante à l’intérieur et entre les cellules. Une fois ce travail achevé, des problèmes pourraient encore se propager suffisamment pour rendre une cellule entière inopérante, mais il serait extrêmement difficile pour un problème de se propager au-delà de cette cellule. Et si nous parvenons à rendre les cellules interchangeables, la reprise sera nettement plus rapide, car nous pourrons basculer vers une autre cellule et empêcher le problème d’affecter les utilisateurs finaux. 

La difficulté réside dans le fait de séparer suffisamment ces cellules pour réduire les risques de propagation des erreurs, tout en maintenant les performances et le bon fonctionnement du système. Dans un système d’infrastructure complexe, les services doivent communiquer entre eux pour partager des requêtes, des informations, des charges de travail, etc. À mesure que nous répliquons ces services dans des cellules, nous devons réfléchir à la manière dont nous gérons la communication entre elles. Dans un monde idéal, nous redirigeons le trafic d’une cellule défaillante vers d’autres cellules saines. Mais comment gérer une « requête fatale » — celle qui rend une cellule défaillante ? Si nous redirigeons cette requête vers une autre cellule, cela peut la rendre défaillante, ce que nous essayons justement d’éviter. Nous devons trouver des mécanismes pour détourner le « bon » trafic des cellules défaillantes tout en détectant et en bloquant le trafic qui provoque la défaillance des cellules. 

À court terme, nous avons déployé des copies des services informatiques dans chaque cellule de calcul afin que la plupart des requêtes adressées au centre de données puissent être traitées par une seule cellule. Nous équilibrons également la charge du trafic entre les cellules. À plus long terme, nous avons commencé à mettre en place un processus de découverte de services de nouvelle génération qui sera exploité par une maillage de services, que nous espérons achever en 2024. Cela nous permettra de mettre en œuvre des politiques sophistiquées qui n'autoriseront la communication inter-cellules que lorsqu'elle n'aura pas d'impact négatif sur les cellules de basculement. Une méthode permettant de diriger les requêtes dépendantes vers une version de service dans la même cellule sera également disponible en 2024, ce qui minimisera le trafic inter-cellules et réduira ainsi le risque de propagation inter-cellules des défaillances.

En période de pointe, plus de 70 % du trafic de nos services back-end est acheminé hors des cellules et nous avons beaucoup appris sur la manière de créer des cellules, mais nous prévoyons de mener davantage de recherches et de tests à mesure que nous poursuivrons la migration de nos services jusqu’en 2024 et au-delà. Au fur et à mesure de nos progrès, ces barrières de protection deviendront de plus en plus solides.

Migration d'une infrastructure toujours active

Roblox est une plateforme mondiale qui prend en charge des utilisateurs partout dans le monde ; nous ne pouvons donc pas déplacer nos services pendant les heures creuses ou les « temps d’arrêt », ce qui complique encore davantage le processus de migration de toutes nos machines vers des cellules et de nos services pour qu’ils fonctionnent dans ces cellules. Nous avons des millions d’expériences fonctionnant en continu qui doivent continuer à être prises en charge, même pendant que nous déplaçons les machines sur lesquelles elles s’exécutent et les services qui les soutiennent. Lorsque nous avons entamé ce processus, nous ne disposions pas de dizaines de milliers de machines inutilisées et disponibles pour y migrer ces charges de travail. 

Nous disposions toutefois d’un petit nombre de machines supplémentaires achetées en prévision d’une croissance future. Pour commencer, nous avons construit de nouvelles cellules à l’aide de ces machines, puis y avons migré les charges de travail. Nous accordons autant d’importance à l’efficacité qu’à la fiabilité ; ainsi, plutôt que d’aller acheter davantage de machines une fois que nous avons épuisé notre stock de machines « de réserve », nous avons construit davantage de cellules en effaçant et en réapprovisionnant les machines depuis lesquelles nous avions effectué la migration. Nous avons ensuite migré les charges de travail vers ces machines réapprovisionnées, puis avons recommencé le processus depuis le début. Ce processus est complexe : à mesure que les machines sont remplacées et libérées pour être intégrées dans des cellules, elles ne se libèrent pas de manière idéale et ordonnée. Elles sont physiquement dispersées dans les salles de données, ce qui nous oblige à les provisionner de manière fragmentée, ce qui nécessite un processus de défragmentation au niveau matériel pour maintenir l’alignement des emplacements matériels avec les domaines de défaillance physique à grande échelle. 

Une partie de notre équipe d’ingénierie d’infrastructure se concentre sur la migration des charges de travail existantes depuis notre environnement hérité, ou « pré-cellulaire », vers des cellules. Ce travail se poursuivra jusqu’à ce que nous ayons migré des milliers de services d’infrastructure différents et des milliers de services back-end vers des cellules nouvellement construites. Nous prévoyons que cela prendra toute l’année prochaine et s’étendra peut-être jusqu’en 2025, en raison de certains facteurs de complication. Tout d’abord, ce travail nécessite la mise au point d’outils robustes. Par exemple, nous avons besoin d’outils pour rééquilibrer automatiquement un grand nombre de services lorsque nous déployons une nouvelle cellule, sans impact sur nos utilisateurs. Nous avons également constaté que certains services avaient été conçus en partant d’hypothèses concernant notre infrastructure. Nous devons réviser ces services afin qu’ils ne dépendent pas d’éléments susceptibles d’évoluer à l’avenir, à mesure que nous passons aux cellules. Nous avons également mis en place à la fois un moyen de rechercher les modèles de conception connus qui ne fonctionneraient pas bien avec l’architecture cellulaire, ainsi qu’un processus de test méthodique pour chaque service migré. Ces processus nous aident à prévenir tout problème pour les utilisateurs causé par l’incompatibilité d’un service avec les cellules.

Aujourd’hui, près de 30 000 machines sont gérées par des cellules. Cela ne représente qu’une fraction de notre parc total, mais la transition s’est déroulée sans heurts jusqu’à présent, sans impact négatif pour les joueurs. Notre objectif ultime est que nos systèmes atteignent un temps de disponibilité de 99,99 % chaque mois, ce qui signifie que nous ne perturberions pas plus de 0,01 % des heures d'activité. À l'échelle du secteur, les temps d'arrêt ne peuvent pas être complètement éliminés, mais notre objectif est de réduire les temps d'arrêt de Roblox à un niveau tel qu'ils soient pratiquement imperceptibles.

Assurer la pérennité de notre système à mesure que nous évoluons

Bien que nos premiers efforts s’avèrent fructueux, notre travail sur les cellules est loin d’être terminé. À mesure que Roblox continue de se développer, nous continuerons à travailler pour améliorer l’efficacité et la résilience de nos systèmes grâce à cette technologie et à d’autres. Au fur et à mesure, la plateforme deviendra de plus en plus résistante aux problèmes, et tout incident qui se produirait devrait devenir progressivement moins visible et moins perturbant pour les utilisateurs de notre plateforme.

En résumé, à ce jour, nous avons : 

  • Construit un deuxième centre de données et atteint avec succès le statut actif/passif. 
  • Créé des cellules dans nos centres de données actifs et passifs et migré avec succès plus de 70 % du trafic de nos services back-end vers ces cellules.
  • Mise en place des exigences et des bonnes pratiques que nous devrons suivre pour maintenir l'uniformité de toutes les cellules à mesure que nous continuons à migrer le reste de notre infrastructure. 
  • Lancé un processus continu visant à renforcer les « murs anti-explosion » entre les cellules. 

À mesure que ces cellules deviendront plus interchangeables, il y aura moins d’interférences entre elles. Cela nous ouvre des perspectives très intéressantes en termes d’automatisation accrue de la surveillance, du dépannage et même du transfert automatique des charges de travail. 

En septembre, nous avons également commencé à mener des expériences en mode actif/actif dans nos centres de données. Il s’agit d’un autre mécanisme que nous testons pour améliorer la fiabilité et réduire au minimum les temps de basculement. Ces expériences ont permis d’identifier un certain nombre de modèles de conception de système, principalement liés à l’accès aux données, que nous devons retravailler à mesure que nous progressons vers un mode entièrement actif/actif. Dans l’ensemble, l’expérience s’est avérée suffisamment concluante pour que nous la laissions en place pour le trafic provenant d’un nombre limité de nos utilisateurs. 

Nous sommes ravis de poursuivre ce travail afin d'améliorer l'efficacité et la résilience de la plateforme. Ces travaux sur les cellules et l'infrastructure active-active, associés à nos autres efforts, nous permettront de devenir un service fiable et hautement performant pour des millions de personnes, et de continuer à évoluer à mesure que nous nous efforçons de connecter un milliard de personnes en temps réel.