Les trois concepts de panne dont vous devez connaître
Bienvenue
Les systèmes distribués échouent selon des modèles. Une fois que vous connaissez ces modèles, chaque postmortem devient un exercice de reconnaissance au lieu d'être un mystère.
Trois concepts couvrent la plupart de ce qui compte dans l'analyse des pannes en production:
Point unique de panne (SPOF): un composant dont l'échec entraîne la panne d'un système plus large. Ce sont souvent des pannes cachées : le serveur DNS sur lequel tout le monde dépend ; le certificat qui se renouvelle contre lequel tout se fait ; le seul serveur de base de données.
Panne en chaîne: l'échec d'un composant déclenche celui d'un autre, qui déclenche encore un autre. Une base de données lent provoque des temps d'attente dans le niveau API, qui provoque des tentatives supplémentaires, qui chargent encore la base de données, qui provoque encore plus de temps d'attente. L'explosion se propage.
Rayon d'action: combien de la système s'arrête quand une pièce échoue. Les choix architecturaux limitent ou élargissent le rayon. Un SPOF a un rayon d'action non limité. Un service isolé a un rayon limité.
Au terme de cette leçon, vous serez capable de:
- Identifier les SPOFs dans une architecture par inspection
- Reconnaître les modèles de pannes en chaîne : troupeau tonnerre, tempête de tentatives, file d'attente de la mort
- Lire un vrai calendrier & séparer la cause initiale de la défaillance latente que la cause initiale a mise à jour
- Écrire des actions sans faute qui ciblent les systèmes au lieu des personnes, couvrant la prévention / détection / récupération
- Réfléchir aux bulkheads & aux circuits de rupture comme des outils limitant le rayon d'action
Repérez le point unique de panne
Inspection de l'architecture en couches
Considérez une petite architecture web :
- DNS: api.example.com -> seule IP de serveur de noms 203.0.113.10 hébergée par un seul fournisseur de DNS
- CDN: un seul fournisseur de CDN devant `api.example.com
- Ingress: deux machines de proxy inversé derrière un équilibreur de charge
- Backend: six instances API dans deux zones de disponibilité (trois par zone)
- Base de données: une primaire + une seconde, dans la même zone de disponibilité
- Cache: cluster Redis, trois nœuds répartis dans les mêmes deux zones de disponibilité
Question: quelles composantes sont des SPOFs? Connaissance: les SPOFs ne sont pas toujours évidents. Un cluster de trois machines toutes dans une même zone de disponibilité est un SPOF pour l'échec de cette zone.
Trois modèles de cascade classiques
Les perte se propagent par les dépendances
Modèle 1 : Meute de tonnerre. Un resource partagée (cache, verrou, base de données) échoue ou redémarre. Chaque client qui en dépend tente à nouveau. La vague envahit ce qui reprend le fonctionnement; les tentatives empilées surchargent la récupération; la récupération ne se termine jamais.
Modèle 2 : Tempête de tentatives. Un service downstream ralentit. Les appels upstream, au lieu d'échouer, tente à nouveau. Les tentatives se multiplient par le charge initial. Le service ralentit davantage, déclenchant plus de tentatives. Enfin, la charge dépasse même une version saine du service.
Modèle 3 : File de mort. Une file d'attente de traitement sans pression arrière reçoit plus vite qu'il ne traite. La file grandit sans limite. La mémoire s'épuise; le consommateur s'arrête; redémarr; trouve une file plus grande; s'arrête encore.
Fil conducteur commun: une petite perturbation initiale déclenche un boucle à positif retour. La réponse du système amplifie la perte plutôt que de l'atténuer.
Mécanismes d'atténuation
Retard exponentiel avec bruit. Les clients qui tente d'attendre plus longtemps à chaque fois, avec un décalage aléatoire. Prévent les vagues synchronisées de tentatives.
Circuit briseur. Un appelleur suit le taux de perte downstream. Au-delà d'un seuil, l'appelant arrête d'appeler pendant un délai de refroidissement et échoue immédiatement à ses propres demandes.
Écoutille. Isoler les resources par dépendance. Piscine A pour la base de données, piscine B pour le cache. Une base de données lente ne peut pas épuiser toutes les connexions; les appels au cache continuent.
Échauffement de charge. Lorsqu'elle est surchargée, rejeter les demandes au niveau de l'extérieur au lieu d'accepter et d'échouir lentement. Un 429 en 1 ms est mieux qu'un 500 en 30 secondes.
Surpression. Lentes producteurs lorsque les consommateurs ne peuvent pas tenir. Les files deviennent limitées; les émetteurs bloquent; la source originale de travail ressent la friction.
Diagnostiquer une Cascade
Un équipe de niveau API fond en fusion lors d'un redémarrage de base de données. Chronologie:
- 14:00:00 — l'opérateur promeut la base de données de secours. Désavailability prévue : ~10 secondes.
- 14:00:08 — la base principale est indisponible. Les demandes de niveau API échouent avec des erreurs de connexion de base de données.
- 14:00:08 — Le niveau API tente de nouveau (configuration par défaut : 5 tentatives, sans recul, 100ms d'intervalle).
- 14:00:11 — la base de secours est promue et accepte de nouvelles connexions.
- 14:00:11 — Le niveau API ouvre des milliers de nouvelles connexions à la base de données simultanément (chaque réplica × chaque demande concurren
- 14:00:13 — La connexion de pool de la nouvelle base principale est épuisée; les nouvelles connexions sont rejetées.
- 14:00:13-14:05:00 — Les réplicas de niveau API épuisent les pools de connexions, jettent des exceptions, redémarr
- 14:05:00 — L'opérateur arrête manuellement le trafic de niveau API; la base de données se stabilise.
- 14:10:00 — La restauration progressive du trafic est terminée. Perte totale : ~10 minutes (contre prévu : ~10 secondes).
SERVFAIL DNS: Deux Désastres Composés
Un Postmortem de Forme Réelle
Ce qui suit est une version affinée d'un véritable incident. Les noms des fournisseurs ont été modifiés, les adresses IP ont été anonymisées; la forme, le calendrier et les leçons sont réels.
Résumé
Le site example.com a renvoyé SERVFAIL de toutes les résolutions DNS publiques pendant environ 3-4 heures. Toutes les autres zones sur la même maître de base de données n'étaient pas concernées. Cause racine : deux désastres composés.
1. Le fournisseur A (un fournisseur de DNS secondaire) a ajouté une nouvelle IP de synchronisation interne qui n'était pas dans la liste d'autorisation allow-axfr-ips de la base principale.
2. La zone example.com avait un conflit de CNAME datant de plusieurs années (RFC-violant) (demo.example.com avait à la fois des enregistrements CNAME et MX/TXT au même étiquette) qui a causé le fournisseur A à rejeter la zone lors d'une nouvelle AXFR.
Calendrier (UTC)
- ~15:00 — Le fournisseur A ajoute une nouvelle IP de synchronisation 198.51.100.42 à leur infrastructure
- 15:02 — premier AXFR-out denied pour 198.51.100.42 apparaît dans les journaux DNS primaires (pas de mise en garde sur ce signal)
- ~18:00 — la fenêtre SOA expire est atteinte; Le fournisseur A supprime la zone example.com de la cache
- ~18:30 — SERVFAIL détecté à l'extérieur
- ~19:45 — cause racine identifiée
- 20:00 — 198.51.100.42 ajouté à allow-axfr-ips; le primaire redémarré
- 20:05 — NOTIFY envoyé; AXFR initié; zone TOUTES PUISSANCE SERVFAIL (conflit CNAME)
- 20:07 — check-zone révèle 1 erreur: conflit CNAME sur demo.example.com
- 20:09 — CNAME remplacé par un enregistrement A; vérification de la zone propre (0 erreurs)
- 20:10 — NOTIFY envoyé; AXFR termine; Fournisseur A commence à servir la zone
- 20:11 — dig @8.8.8.8 example.com A retourne l'IP correcte — RÉSOLU
Pourquoi uniquement example.com?
Les 47 zones partagent la même base DNS primaire. La commande AXFR concerne toutes les zones. Mais seulement example.com avait un conflit CNAME et seulement example.com avait besoin d'une mise à jour AXFR au moment où l'accès était refusé. Les autres zones avaient déjà été mise à jour avant le refus ou n'avaient pas encore besoin de le faire.
Défaut latent
Le conflit CNAME à demo.example.com existait depuis des années. Il fonctionnait parce que le primaire servait la zone à partir de sa base de données (tolérant pour les violations RFC) et que le fournisseur A servait des données de cache obsolètes depuis avant qu'une violation ne soit introduite. Lorsque le fournisseur A a supprimé sa cache et a besoin de données fraîches, la violation a surgi.
Déclencheur
Le fournisseur A a ajouté en silence une nouvelle IP de synchronisation. La liste autorisée de la base primaire ne la mentionnait pas. L'AXFR a été refusé. Trois heures plus tard (SOA expire), le fournisseur A a supprimé la zone. Le défaut latent a surgi lorsque le système a tenté de se rétablir.
Écrire des actions correctives sans reproche
Sans reproche: Cibler les systèmes, pas les personnes
Une action corrective sans reproche nomme quelque chose que le système devrait faire différemment, pas quelque chose que une personne devrait faire différemment. 'Former l'opérateur' est responsable. 'Ajouter une vérification automatique qui détecte ceci avant le déploiement' est sans reproche.
Les bonnes actions correctives sans reproche se regroupent en trois dimensions:
- Prévention: rendre la mauvaise chose plus difficile ou impossible
- Détection: la noter plus tôt si elle se produit
- Récupération: limitant les dommages lorsqu'elle se produit
Chaque élément devrait nommer (1) la modification spécifique du système, (2) une équipe d'exploitation et (3) la dimension qu'il sert.
Les compartiments qui coulent sans le navire
Emprunté de l'ingénierie navale
Les navires emportent des cloisons étanches : des murs verticaux qui divisent l'hull. Un compartiment peut être inondé sans faire couler le navire ; un autre peut échouer sans affecter le reste.
Les systèmes distribués empruntent la même expression & la même idée.
Pattern des cloisons : isoler les ressources par dépendance. Un service qui appelle trois API downstream utilise trois pools de connexions distincts, trois pools de fils de thread distincts, trois budgets de reprise distincts. Une API downstream lente ou en échec ne consomme pas les ressources allouées aux autres deux.
Sans cloisons : une dépendance lente consomme la file d'attente de thread partagée ; les appels aux autres dépendances sont bloqués en attente de threads ; le service entier devient inopérant.
Avec cloisons : une dépendance lente consomme sa propre file ; les appels à elle échouent rapidement ; les appels aux autres dépendances continuent normalement ; la zone d'impact reste limitée à la dépendance échouée.
Disjoncteurs
Pattern des disjoncteurs : un enveloppe étatique autour d'une dépendance downstream qui suit le taux de défaillance. Trois états :
- Fermé (normal) : les appels passent. Les échecs sont comptabilisés.
- Ouvert (déclenché) : au-delà d'un seuil de défaillance (par exemple, 50 % d'échecs au cours des 30 dernières secondes), le disjoncteur ouvre. Les appels échouent immédiatement sans tentant la dépendance. Épargne l'appelant du travail inutile ; épargne la dépendance du chargement tout en étant malade.
- Mi-ouvert (essayant) : après une période de refroidissement, le disjoncteur permet à une petite fraction d'appels. S'ils réussissent, il ferme à nouveau au normal. S'ils échouent, il rouvre pour une autre période de refroidissement.
La clé de l'insight : le disjoncteur empêche les efforts inutiles pendant les périodes connues-malades, & donne à la sous-charge une chance de se rétablir sans charge continue.
Les cloisons limitent la zone d'impact. Les disjoncteurs préviennent l'impact de se maintenir.
Limitation de la zone d'impact
Votre service API fait appel à quatre services en aval : Service Utilisateur, Service de recommandation, Service de notification et un API de paiement tiers. L'équipe a entendu dire que le Service de recommandation n'a pas toujours été très fiable et souhaite vous assurer que lorsque celui-ci échoue, le reste du système reste en bonne santé.
Aujourd'hui, le service utilise une seule file d'attente partagée de 200 threads et une seule file d'attente de connexions HTTP partagée. Les quatre services en aval se disputent ces ressources. Il n'y a pas de circuits de rupture.
Conception d'une revue sur les modes de panne
Synthèse
Vous avez appris à repérer les SPOFs par inspection, à reconnaître les modèles de pannes en cascade, à séparer le déclencheur de la défectuosité latente lors de la lecture d'un postmortem, à rédiger des actions correctives sans faute et à limiter l'impact avec des bulkheads, des circuits de rupture et une dégradation gracieuse.
Appliquez les cinq.
Votre équipe lance un nouveau service search.example.com qui dépend de trois services en aval : un index de recherche principal (index.example.com), un service d'analyse (analytics.example.com) et un service de recommandation (recs.example.com). L'équipe souhaite que vous dirigiez une 'revue sur les modes de panne' avant le lancement.
Où ce cours va ensuite
Où ce cours va ensuite
Vous pouvez maintenant repérer un SPOF, reconnaître une cascade, lire un postmortem de manière productive, rédiger des actions correctives sans faute et limiter l'impact par conception.
La dernière leçon de ce cours (cs_distsys_observability_and_capacity) enseigne quoi mesurer pour découvrir qu'un problème se produit avant que les utilisateurs ne le fassent. Les vérifications d'état de santé, les points de terminaison de version, les quatre signaux d'or au niveau d'un nœud proxy et comment les décisions de capacité de surcharge sont liées aux données observées.
Leçon complémentaire: geometry_of_failure_modes_and_blast_radius dérive la centralité de betweenness (quel nœud du graphe est la bouteille d'embouteillage) et le min-coupe (le seuil de la zone d'impact).
Bien fait. En avant.