REL 5: Comment concevez-vous des interactions dans un système distribué pour atténuer ou résister aux défaillances ?
Les systèmes distribués s'appuient sur des réseaux de communication pour interconnecter des composants (tels que des serveurs ou des services). Votre charge de travail doit fonctionner de manière fiable malgré la perte de données ou la latence sur ces réseaux. Les composants du système distribué doivent fonctionner d'une manière qui n'a pas d'impact négatif sur les autres composants ou la charge de travail. Ces bonnes pratiques permettent aux charges de travail de résister aux contraintes ou aux défaillances, de s'en remettre plus rapidement et d'atténuer l'impact de ces déficiences. Il en résulte une amélioration du temps moyen de récupération (MTTR).
Ressources
Retry, backoff, and jitter: AWS re:Invent 2019: Introducing The Amazon Builders’ Library
(DOP328)
Error Retries and Exponential Backoff in AWS
Amazon API Gateway: Throttle API Requests for Better Throughput
The Amazon Builders' Library: Timeouts, retries, and backoff with jitter
The Amazon Builders' Library: Avoiding fallback in distributed systems
The Amazon Builders' Library: Avoiding insurmountable queue backlogs
The Amazon Builders' Library: Caching challenges and strategies
Well-Architected lab: Level 300: Implementing Health Checks and Managing Dependencies
to Improve Reliability
CircuitBreaker (summarizes Circuit Breaker from “Release It!” book)
Michael Nygard “Release It! Design and Deploy Production-Ready Software”
Bonnes pratiques:
-
Implémenter une dégradation appropriée pour transformer les dépendances dures applicables en dépendances souples: Lorsque les dépendances d'un composant ne sont pas saines, le composant lui-même peut continuer de fonctionner, même si de manière dégradée. Par exemple, lorsqu'un appel de dépendance échoue, basculez vers une réponse statique prédéterminée.
-
Demandes de limitation: Il s'agit d'un modèle d'atténuation conçu répondre à une augmentation inattendue de la demande. Certaines demandes sont honorées, mais celles qui dépassent une limite définie sont rejetées et renvoient un message indiquant qu'elles ont été limitées. On attend des clients qu'ils renoncent à leur demande ou qu'ils essaient à nouveau à un taux plus lent.
-
Contrôler et limiter les appels de nouvelle tentative: Utilisez le backoff exponentiel pour réessayer après des intervalles progressivement plus longs. Introduisez l'instabilité pour randomiser ces intervalles de nouvelle tentative et limitez le nombre maximal de nouvelles tentatives.
-
Échec rapide et limite des files d'attente: Si la charge de travail n'est pas en mesure de répondre avec succès à une demande, procédez à son interruption immédiate. Cela permet la libération des ressources associées à une demande et permet au service de récupérer s'il manque de ressources. Si la charge de travail est en mesure de répondre avec succès, mais que le taux de requêtes est trop élevé, utilisez plutôt une file d'attente pour mettre les requêtes en mémoire tampon. N'autorisez toutefois pas les files d'attente longues qui peuvent entraîner le traitement de requêtes obsolètes que le client a déjà abandonnées.
-
Définir les délais d'attente du client: Définissez les délais d'expiration de manière appropriée, vérifiez-les systématiquement et ne comptez pas sur les valeurs par défaut, car elles sont généralement trop élevées
-
Rendre les services sans état dans la mesure du possible: Les services ne doivent pas exiger d'état ou doivent décharger un état de telle sorte qu'entre les différentes demandes client, il n'y ait pas de dépendance vis-à-vis des données stockées localement sur disque ou en mémoire. Cela rend possible le remplacement à volonté des serveurs sans impact sur la disponibilité. Amazon ElastiCache ou Amazon DynamoDB sont de bonnes destinations pour un état déchargé.
-
Mettre en place des leviers d'urgence: Il s'agit de processus rapides qui peuvent atténuer l'impact sur la disponibilité de votre charge de travail. Ils peuvent être exploités en l'absence d'une cause racine. Un levier d'urgence idéal réduit à zéro la charge cognitive sur les résolveurs en fournissant des critères d'activation et de désactivation entièrement déterministes. Les exemples de leviers incluent le blocage de tout le trafic robotique ou le traitement d'une réponse statique. Les leviers sont souvent manuels, mais ils peuvent également être automatisés.
Plan d'amélioration
Implémenter une dégradation appropriée pour transformer les dépendances dures applicables
en dépendances souples
- Le renvoi d'une réponse statique permet d'atténuer les défaillances qui se produisent
dans les dépendances.
Well-Architected lab: Level 300: Implementing Health Checks and Managing Dependencies to Improve Reliability - Détecter quand l'opération de nouvelle tentative est susceptible d'échouer et empêcher
votre client d'effectuer des appels ayant échoué avec le modèle de disjoncteur
CircuitBreaker
Demandes de limitation
- Utiliser Amazon API Gateway
Throttle API Requests for Better Throughput
Contrôler et limiter les appels de nouvelle tentative
Error Retries and Exponential Backoff in AWS
- Les kits Amazon SDK la mettent en œuvre par défaut. Mettez en place une logique similaire dans votre couche de dépendance lors de l'appel de vos propres services dépendants. Déterminez quels sont les délais d'expiration et quand les nouvelles tentatives doivent s'arrêter en fonction de votre cas d'utilisation.
Échec rapide et limite des files d'attente
- Procéder à une interruption immédiate lorsque le service est sous pression
Fail Fast - Limiter les files d'attente: Dans un système basé sur les files d'attente, la charge du message peut s'accumuler
dans une importante file d'attente lorsque le traitement s'arrête, mais que les messages
continuent d'arriver, ce qui augmente le temps de traitement. Les travaux peuvent
être achevés trop tard pour que les résultats soient utiles, ce qui entraîne essentiellement
le problème de disponibilité que la file d'attente était censée permettre d'éviter.
The Amazon Builders' Library: Avoiding insurmountable queue backlogs
Définir les délais d'attente du client
AWS SDK: Retries and Timeouts
Rendre les services sans état dans la mesure du possible
- Supprimez les états qui peuvent être stockés dans les paramètres de demande.
- Certaines données (comme les cookies) peuvent être transmises dans les en-têtes ou les paramètres de requête
- Réfactorisez afin de supprimer l'état qui peut rapidement être transmis dans les requêtes
- Après avoir vérifié si l'état est requis, déplacez tout suivi d'état vers un cache
multizone ou un magasin de données résilient comme Amazon ElastiCache, Amazon RDS,
Amazon DynamoDB ou une solution de données distribuées tierce.: Enregistrez un état qui n'a pas pu être déplacés vers des magasins de données résilient.
- Certaines données ne sont pas forcément nécessaires pour certaines requêtes et peuvent être récupérées à la demande.
- Supprimez les données qui peuvent être récupérées de manière asynchrone.
- Choisissez un magasin de donnée qui répond aux exigences relatives à l'état requis.
- Pensez à avoir une base de données NoSQL pour les données non relationnelles.
Mettre en place des leviers d'urgence
- Conseils pour implémenter et utiliser des leviers d'urgence
- Lorsque les leviers sont activés, faites MOINS, pas plus.
- Gardez la tâche simple, évitez les comportements bimodaux.
- Testez régulièrement vos leviers.
- Tels sont des exemples d'actions qui NE sont PAS des leviers d'urgence.
- Ajouter de la capacité
- Appelez les propriétaires de services des clients qui dépendent de votre service et demandez-leur de réduire les appels.
- Apporter une modification au code et le diffuser