L'article décrit la possibilité d'assurer la disponibilité d'un service Web déployé dans le cloud en cas de dysfonctionnement du datacenter. La solution proposée repose sur un compromis consistant en
une duplication partielle : un système de sauvegarde est déployé dans un autre datacenter, qui peut fonctionner dans un mode de fonctionnalité limitée lorsque le datacenter principal n'est pas disponible. Ce schéma est principalement destiné à l'application pour les défaillances à court terme, mais offre également la possibilité de transformer rapidement le système de sauvegarde en système principal en cas de problèmes à grande échelle.

Description du problème
L'année dernière, nous avons été touchés par un incident dans le centre de données d'un célèbre fournisseur de cloud - l'un de nos services n'a pas été accessible aux utilisateurs pendant une demi-heure. Ensuite, nous avons vu de nos propres yeux qu'en cas de problèmes dans le centre de données cloud, il n'y a pratiquement pas de leviers pour restaurer l'application au travail, et pour l'équipe responsable de l'application, il ne reste plus qu'à mettre en place et attendre. Cette expérience nous a fait sérieusement réfléchir à l'utilisation du cloud pour nos produits.
Ce qui s'est exactement passé ce jour-là n'a jamais été découvert. Nous sommes habitués à percevoir les nuages comme un avant-poste indestructible, mais ce n'est pas le cas. La vérité est qu'il n'y a pas de garantie à cent pour cent de la disponibilité des services dans le cloud, comme dans tout autre endroit. Les nuages sont une abstraction derrière laquelle se cachent tous les mêmes racks de fer dans les centres de données et le facteur humain. Tout matériel tombe tôt ou tard en panne (bien que les pannes matérielles des centres de données soient plus susceptibles de se produire régulièrement). En outre, il
existe des cas de problèmes plus graves conduisant à l'inaccessibilité des centres de données: incendies, attaques DDoS, catastrophes naturelles, coupures d'électricité et d'Internet, etc.
Si nous parlons du facteur humain, ce n'est pas la dernière cause d'accidents:
"selon les statistiques, dans 80% des défaillances de l'infrastructure réseau, les gens sont à blâmer" . Peu importe à quel point ils sont bien intentionnés, les gens ne sont pas fiables. Même vous et vos collègues - des personnes directement intéressées par la stabilité des produits pris en charge - avez probablement fait des erreurs, sans parler du personnel de la société de quelqu'un d'autre, pour qui vos instances ne sont pas différentes de milliers d'autres. Quelle que soit l'équipe professionnelle derrière l'infrastructure, un nouveau problème est une question de temps.
Tout a un prix. Lorsque vous passez au cloud, vous obtenez une abstraction simple, pratique à utiliser, une faible dépendance à l'égard de votre service des opérations en échange d'un contrôle total sur la situation. Dans ce cas, si vous ne prenez pas soin de vous à l'avance, ayant prévu la possibilité d'erreurs d'autrui, personne ne le fera.
Options de solution
Pour nous, l'indisponibilité du service, même pendant plusieurs minutes, est déjà critique. Par conséquent, nous avons décidé de trouver un moyen de nous assurer contre des problèmes similaires à l'avenir, sans abandonner les nuages.
Lorsque l'on commence à résoudre le problème de la disponibilité des services dans le cloud, il convient de garder à l'esprit que l'accessibilité est un concept assez large et, en fonction de ce qu'il signifie, différents scénarios de sa fourniture sont envisagés. Bien que cet article ne traite que du problème d'accessibilité à la suite d'une défaillance du centre de données, il serait approprié de dire quelques mots sur les solutions à d'autres problèmes d'accessibilité.
La disponibilité comme une opportunité technique pour donner accès à une ressource pendant un temps spécifique à une certaine charge. Le problème se produit lorsque le service est en cours d'exécution, mais en raison des ressources limitées et du cadre architectural du système, tous les utilisateurs ne peuvent pas y accéder dans un certain temps de réponse. La tâche est le plus souvent résolue en déployant des instances supplémentaires avec l'application. Avec cette mise à l'échelle, les nuages font un excellent travail.
L'accessibilité comme la disponibilité d'un service Web pour les utilisateurs d'une région spécifique. La solution évidente ici est le sharding. En d'autres termes, diviser le système en plusieurs applications indépendantes dans différents centres de données avec ses propres données et affecter chaque utilisateur à son instance de système, par exemple, en fonction de sa géolocalisation. Lors du partage, la défaillance d'un centre de données dans le pire des cas entraînera l'indisponibilité du service pour une partie seulement des utilisateurs liés à ce centre de données. Pas le dernier argument en faveur du partage - c'est un temps de ping différent du centre de données dans différentes régions.
Cependant, les restrictions imposées à l'utilisation du cloud et le besoin de décentralisation sont souvent des exigences législatives qui sont généralement prises en compte même au stade de la conception du système. Ces exigences comprennent: la loi Yarovaya - le stockage des données personnelles (PD) des utilisateurs en Russie; Règlement général sur la protection des données (RGPD) - restrictions sur le transfert transfrontalier de PD des utilisateurs de l'UE vers certains pays; et la censure chinoise sur Internet, où TOUTES les communications et TOUTES les parties de l'application doivent être situées en Chine et, de préférence, sur leurs serveurs.
Le problème de l'inaccessibilité technique du centre de données est résolu en dupliquant le service dans un autre centre de données. Ce n'est pas une tâche technique facile. Le principal obstacle au déploiement parallèle de services dans différents centres de données est la base de données. En règle générale, les petits systèmes utilisent une architecture à assistant unique. Dans ce cas, la défaillance du centre de données avec le maître rend l'ensemble du système inopérant. Un schéma de réplication maître de réplication est possible, mais il impose de fortes limitations que tout le monde ne comprend pas. En fait, il ne met pas à l'échelle l'enregistrement dans la base de données, mais donne même une petite pénalité de temps, car il est nécessaire de confirmer à tous les nœuds que la transaction a été acceptée. Le temps de l'opération d'écriture augmente encore plus lorsque les nœuds doivent être espacés dans différents centres de données.
Justification de la décision
L'analyse de la charge sur notre service a montré qu'en moyenne environ 70% des appels à l'API sont effectués par des méthodes GET. Ces méthodes utilisent une base de données en lecture seule.
Distribution d'appels de méthode HTTP de service WebJe pense que ces résultats reflètent l'ensemble des services Web généralement disponibles. Par conséquent, nous pouvons dire que
dans l'API de service Web moyenne, les méthodes de lecture sont appelées beaucoup plus souvent que les méthodes d'écriture .
La deuxième déclaration que je voudrais faire valoir est que
si nous parlons d'accessibilité absolue, les clients du service ont vraiment besoin d'une telle accessibilité non seulement de la richesse des méthodes d'API disponibles, mais seulement de celles qui sont nécessaires pour continuer le travail «habituel» avec le système. et effectuer des requêtes "normales" . Personne ne sera contrarié si une méthode à laquelle on accède plusieurs fois par mois n'est pas disponible pendant plusieurs minutes. Souvent, le flux «normal» est couvert par des méthodes de lecture.
Par conséquent, garantir la disponibilité absolue de méthodes de lecture uniquement peut déjà être considéré comme une option possible pour une solution à court terme au problème de la disponibilité du système en cas de défaillance du centre de données.Que voulons-nous mettre en œuvre
En cas de pannes dans le centre de données, nous souhaitons transférer le trafic vers un système de sauvegarde dans un autre centre de données. Dans le système de sauvegarde, toutes les méthodes de lecture doivent être disponibles, et lors de l'appel des méthodes restantes, s'il est impossible de se passer de l'écriture dans la base de données, l'erreur correcte doit être affichée.
En fonctionnement normal, la demande de l'utilisateur est envoyée à l'équilibreur, qui à son tour la redirige vers l'API principale. Si le service principal n'est pas disponible, l'équilibreur détermine ce fait et redirige les demandes vers le système de sauvegarde fonctionnant en mode de fonctionnalité limitée. À ce moment, l'équipe analyse le problème et décide d'attendre la restauration du centre de données ou de basculer le système de sauvegarde en mode principal.

Algorithme d'implémentation
Changements d'infrastructure nécessaires
- Création d'une réplication esclave de base de données dans un autre centre de données.
- Configuration d'un déploiement de service Web, collecte de journaux, de métriques dans le deuxième centre de données.
- La configuration de l'équilibreur pour la commutation du trafic vers un centre de données de rechange au cas où le premier ne serait pas disponible.
Modifications du code:
- Ajout d'une connexion distincte à la réplique dans le service Web.
- Migrez toutes les routes d'API en lecture seule vers une réplique.
- Pour les méthodes restantes, l'introduction du mode lecture seule via une variable d'environnement ou un autre déclencheur, dans lequel ils fonctionneront partiellement au lieu d'écrire dans la base de données, ou si leur fonctionnalité se casse sans écrire dans la base de données, donne une erreur correcte.
- Améliorations sur le frontend pour afficher l'erreur correcte lors de l'appel des méthodes d'enregistrement.
Avantages et inconvénients de la solution décrite
Les avantages
- Le principal avantage du schéma proposé est qu'il existe toujours un service en double, à tout moment prêt à servir les utilisateurs. En cas de problème avec le centre de données principal, vous n'aurez pas à écrire de scripts de déploiement sur une autre infrastructure et à tout exécuter à la hâte.
- La solution est peu coûteuse à mettre en œuvre et à entretenir. Si vous avez une architecture de microservices et que le produit a besoin non pas d'un mais de plusieurs services, alors dans ce cas, il ne devrait pas y avoir de problèmes particuliers avec le transfert de tous les microservices vers ce schéma.
- Il n'y a aucune menace de perte de données, car il existe toujours une copie complète de la base de données sur la réplique dans un autre centre de données.
- La solution est principalement destinée à la commutation temporaire du trafic, jusqu'à une demi-heure. C'est cette demi-heure qui ne suffit pas pour naviguer en cas de problème avec l'infrastructure. Si pendant cette période, le premier centre de données n'est pas restauré, la réplique esclave de la base de données se transforme en maître et le service en double devient le principal.
- Dans le schéma proposé, l'application et la base de données se trouvent dans le même centre de données. Si vous avez une API et une base de données dans différents centres de données, il est préférable de les transférer vers un seul: cela réduira considérablement le temps d'exécution des requêtes. Par exemple, nos mesures ont montré que pour Google Cloud, la demande de l'API à la base de données dans un centre de données est en moyenne de 6 ms, et lorsque vous allez pour des données vers un autre centre de données, le temps augmente de dizaines de millisecondes.
Inconvénients
- L'inconvénient principal de l'ensemble du système est que pour la commutation instantanée du trafic, un équilibreur est requis qui n'est pas situé dans le même centre de données avec le service principal. L'équilibreur est le point d'échec: si le centre de données avec l'équilibreur tombe en panne, votre service devient de toute façon indisponible.
- La nécessité de déployer le code sur un autre serveur, de surveiller des ressources supplémentaires - par exemple, de surveiller la réplique afin qu'il n'y ait pas de décalage.
Conclusion
Vous ne pouvez pas créer un système résistant à tous les types de pannes. Néanmoins, vous protéger contre certains types est une tâche réalisable. La solution décrite dans l'article, qui permet d'assurer la disponibilité de l'application en cas de dysfonctionnements dans le datacenter, peut être intéressante et utile dans de nombreuses applications pratiques.
La conversion d'un service Web ordinaire en un système entièrement distribué afin de se protéger contre les défaillances hypothétiques dans le centre de données est très probablement impossible. À première vue, même le schéma proposé semble redondant et «lourd», mais ces inconvénients sont plus que chevauchés par ses avantages et sa facilité de mise en œuvre. Vous pouvez faire une analogie avec l'assurance-accidents: il est fort probable que vous n'aurez jamais besoin d'une telle assurance, mais si un accident se produit, ce sera le bienvenu. Avec le schéma proposé, vous serez sûr d'avoir toujours un système de sauvegarde prêt, qui, pour les problèmes à court terme, garantira la disponibilité de la plupart des méthodes de service, et en cas de longues pannes, il peut devenir complètement le principal en quelques minutes. Beaucoup accepteront de payer ce prix pour une telle confiance.
Chaque système a ses propres paramètres de charge et exigences d'accessibilité. C'est pourquoi il n'y a pas de bonne ou de mauvaise réponse à la question: "Pouvez-vous faire entièrement confiance à Google Cloud ou AWS?" - dans chaque situation spécifique, il sera le sien.