Modèle d’orchestration de saga - AWS Conseils prescriptifs

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Modèle d’orchestration de saga

Intention

Le modèle d’orchestration de saga utilise un coordinateur central (orchestrateur) pour aider à préserver l’intégrité des données dans les transactions distribuées qui couvrent plusieurs services. Dans une transaction distribuée, plusieurs services peuvent être appelés avant qu’une transaction ne soit terminée. Lorsque les services stockent des données dans différents magasins de données, il peut être difficile de maintenir la cohérence des données entre ces magasins de données.

Motivation

Une transaction est une unité de travail unique qui peut impliquer plusieurs étapes, toutes les étapes étant entièrement exécutées ou aucune étape n’étant exécutée, ce qui permet à un magasin de données de conserver son état cohérent. Les termes atomicité, cohérence, isolement et durabilité (ACID) définissent les propriétés d’une transaction. Les bases de données relationnelles fournissent des transactions ACID pour maintenir la cohérence des données.

Pour maintenir la cohérence d’une transaction, les bases de données relationnelles utilisent la méthode de validation en deux phases (2PC). Il s’agit d’une phase de préparation et d’une phase de validation.

  • Au cours de la phase de préparation, le processus de coordination demande aux processus participants à la transaction (participants) de promettre de valider ou d’annuler la transaction.

  • Dans la phase de validation, le processus de coordination demande aux participants de valider la transaction. Si les participants ne parviennent pas à s’engager lors de la phase de préparation, la transaction est annulée.

Dans les systèmes distribués qui suivent un modèle de database-per-service conception, la validation en deux phases n'est pas une option. En effet, chaque transaction est distribuée entre différentes bases de données et aucun contrôleur ne peut coordonner un processus similaire à la validation en deux phases dans les magasins de données relationnels. Dans ce cas, une solution consiste à utiliser le modèle d’orchestration de saga.

Applicabilité

Utilisez le modèle d’orchestration de saga lorsque :

  • Votre système a besoin de l’intégrité et de la cohérence des données dans les transactions distribuées qui s’étendent sur plusieurs magasins de données.

  • Le magasin de données ne propose pas de 2PC pour les transactions ACID, et que la mise en œuvre de 2PC dans les limites de l’application est une tâche complexe.

  • Vous avez des bases de données NoSQL qui ne fournissent pas de transactions ACID et vous devez mettre à jour plusieurs tables au cours d’une seule transaction.

Problèmes et considérations

  • Complexité : les transactions compensatoires et les nouvelles tentatives ajoutent de la complexité au code de l’application, ce qui peut entraîner des frais de maintenance.

  • Cohérence à terme : le traitement séquentiel des transactions locales aboutit à une cohérence à terme, ce qui peut être un défi dans les systèmes nécessitant une forte cohérence. Vous pouvez résoudre ce problème en définissant les attentes de vos équipes métier en ce qui concerne le modèle de cohérence ou en optant pour un magasin de données offrant une forte cohérence.

  • Idempotence : les participants à la saga doivent être idempotents pour permettre des exécutions répétées en cas de défaillances transitoires causées par des pannes inattendues ou des défaillances de l’orchestrateur.

  • Isolement des transactions : la saga n’est pas isolée des transactions. L’orchestration simultanée de transactions peut entraîner l’obsolescence des données. Nous vous recommandons d’utiliser le verrouillage sémantique pour gérer de tels scénarios.

  • Observabilité : l’observabilité fait référence à la journalisation et au suivi détaillés pour résoudre les problèmes liés au processus d’exécution et d’orchestration. Cela devient important lorsque le nombre de participants à la saga augmente, ce qui complique le débogage.

  • Problèmes de latence : les transactions compensatoires peuvent ajouter de la latence au temps de réponse global lorsque la saga comporte plusieurs étapes. Évitez les appels synchrones dans de tels cas.

  • Point de défaillance unique : l’orchestrateur peut devenir un point de défaillance unique, car il coordonne l’ensemble de la transaction. Dans certains cas, le modèle de chorégraphie de saga est préféré en raison de ce problème.

Mise en œuvre

Architecture de haut niveau

Dans le schéma d’architecture suivant, l’orchestrateur de saga compte trois participants : le service de commande, le service d’inventaire et le service de paiement. Trois étapes sont nécessaires pour terminer la transaction : T1, T2 et T3. L’orchestrateur de saga connaît les étapes et les exécute dans l’ordre requis. Lorsque l’étape T3 échoue (échec de paiement), l’orchestrateur exécute les transactions compensatoires C1 et C2 pour rétablir les données dans leur état initial.

Architecture de haut niveau de l’orchestrateur de saga

Vous pouvez utiliser AWS Step Functions pour implémenter l’orchestration de saga lorsque la transaction est distribuée sur plusieurs bases de données.

Mise en œuvre à l’aide des services AWS

L’exemple de solution utilise le flux de travail standard de Step Functions pour implémenter le modèle d’orchestration de saga.

Mise en œuvre du flux de travail de saga avec Step Functions

Lorsqu’un client appelle l’API, la fonction Lambda est invoquée et le prétraitement est effectué dans la fonction Lambda. La fonction lance le flux de travail Step Functions pour commencer à traiter la transaction distribuée. Si aucun prétraitement n’est requis, vous pouvez lancer le flux de travail Step Functions directement depuis API Gateway sans utiliser la fonction Lambda.

L’utilisation de Step Functions atténue le problème du point de défaillance unique, inhérent à la mise en œuvre du modèle d’orchestration de saga. Step Functions intègre une tolérance aux pannes et maintient la capacité de service dans plusieurs zones de disponibilité dans chaque Région AWS afin de protéger les applications contre les pannes individuelles de machines ou de centres de données. Cela permet de garantir une haute disponibilité à la fois pour le service lui-même et pour le flux de travail des applications qu’il gère.

Flux de travail Step Functions

La machine d’état Step Functions vous permet de configurer les exigences de flux de contrôle basées sur les décisions pour la mise en œuvre du modèle. Le flux de travail Step Functions appelle les différents services pour le placement des commandes, la mise à jour de l’inventaire et le traitement des paiements afin de terminer la transaction et envoie une notification d’événement pour un traitement ultérieur. Le flux de travail Step Functions agit en tant qu’orchestrateur pour coordonner les transactions. Si le flux de travail contient des erreurs, l’orchestrateur exécute les transactions compensatoires pour garantir le maintien de l’intégrité des données dans tous les services.

Le schéma suivant illustre les étapes du flux de travail Step Functions. Les étapes Place Order, Update Inventory et Make Payment indiquent le chemin à suivre pour réussir. La commande est passée, l’inventaire est mis à jour et le paiement est traité avant qu’un état Success ne soit renvoyé à l’appelant.

Les fonctions Lambda Revert Payment, Revert Inventory et Remove Order indiquent les transactions compensatoires que l’orchestrateur exécute en cas d’échec d’une étape du flux de travail. Si le flux de travail échoue à l’étape Update Inventory, l’orchestrateur appelle les étapes Revert Inventory et Remove Order avant de renvoyer un état Fail à l’appelant. Ces transactions compensatoires garantissent le maintien de l’intégrité des données. L’inventaire revient à son niveau initial et la commande est annulée.

Flux de travail de saga Step Functions

Exemple de code

L’exemple de code suivant montre comment créer un orchestrateur de saga à l’aide de Step Functions. Pour consulter le code complet, consultez le GitHubréférentiel de cet exemple.

Définitions de tâche

var successState = new Succeed(this,"SuccessState"); var failState = new Fail(this, "Fail"); var placeOrderTask = new LambdaInvoke(this, "Place Order", new LambdaInvokeProps { LambdaFunction = placeOrderLambda, Comment = "Place Order", RetryOnServiceExceptions = false, PayloadResponseOnly = true }); var updateInventoryTask = new LambdaInvoke(this,"Update Inventory", new LambdaInvokeProps { LambdaFunction = updateInventoryLambda, Comment = "Update inventory", RetryOnServiceExceptions = false, PayloadResponseOnly = true }); var makePaymentTask = new LambdaInvoke(this,"Make Payment", new LambdaInvokeProps { LambdaFunction = makePaymentLambda, Comment = "Make Payment", RetryOnServiceExceptions = false, PayloadResponseOnly = true }); var removeOrderTask = new LambdaInvoke(this, "Remove Order", new LambdaInvokeProps { LambdaFunction = removeOrderLambda, Comment = "Remove Order", RetryOnServiceExceptions = false, PayloadResponseOnly = true }).Next(failState); var revertInventoryTask = new LambdaInvoke(this,"Revert Inventory", new LambdaInvokeProps { LambdaFunction = revertInventoryLambda, Comment = "Revert inventory", RetryOnServiceExceptions = false, PayloadResponseOnly = true }).Next(removeOrderTask); var revertPaymentTask = new LambdaInvoke(this,"Revert Payment", new LambdaInvokeProps { LambdaFunction = revertPaymentLambda, Comment = "Revert Payment", RetryOnServiceExceptions = false, PayloadResponseOnly = true }).Next(revertInventoryTask); var waitState = new Wait(this, "Wait state", new WaitProps { Time = WaitTime.Duration(Duration.Seconds(30)) }).Next(revertInventoryTask);

Définitions de Step Functions et des machines d’état

var stepDefinition = placeOrderTask .Next(new Choice(this, "Is order placed") .When(Condition.StringEquals("$.Status", "ORDER_PLACED"), updateInventoryTask .Next(new Choice(this, "Is inventory updated") .When(Condition.StringEquals("$.Status", "INVENTORY_UPDATED"), makePaymentTask.Next(new Choice(this, "Is payment success") .When(Condition.StringEquals("$.Status", "PAYMENT_COMPLETED"), successState) .When(Condition.StringEquals("$.Status", "ERROR"), revertPaymentTask))) .When(Condition.StringEquals("$.Status", "ERROR"), waitState))) .When(Condition.StringEquals("$.Status", "ERROR"), failState)); var stateMachine = new StateMachine(this, "DistributedTransactionOrchestrator", new StateMachineProps { StateMachineName = "DistributedTransactionOrchestrator", StateMachineType = StateMachineType.STANDARD, Role = iamStepFunctionRole, TracingEnabled = true, Definition = stepDefinition });

GitHub référentiel

Pour une implémentation complète de l'exemple d'architecture pour ce modèle, consultez le GitHub référentiel à l'adresse https://github.com/aws-samples/ saga-orchestration-netcore-blog.

Références du blog

Contenu connexe

Vidéos

La vidéo suivante explique comment implémenter le modèle d'orchestration de la saga en utilisant AWS Step Functions.