Partager via


Considérations relatives aux données pour les microservices

Cet article décrit les considérations relatives à la gestion des données dans une architecture de microservices. Chaque microservice gère ses propres données, de sorte que l’intégrité des données et la cohérence des données présentent des défis critiques.

Deux services ne doivent pas partager un magasin de données. Chaque service gère son propre magasin de données privé, et d’autres services ne peuvent pas y accéder directement. Cette règle empêche le couplage involontaire entre les services, qui se produit lorsque les services partagent les mêmes schémas de données sous-jacents. Si le schéma de données change, la modification doit être coordonnée sur chaque service qui s’appuie sur cette base de données. L’isolation du magasin de données de chaque service limite l’étendue du changement et préserve l’agilité des déploiements indépendants. Chaque microservice peut également avoir des modèles de données uniques, des requêtes ou des modèles de lecture et d’écriture. Un magasin de données partagé limite la capacité de chaque équipe à optimiser le stockage des données pour son service spécifique.

Diagramme montrant une approche incorrecte de la séparation des responsabilités des requêtes de commande (CQRS).

Le diagramme montre le service A et une base de données dans une section à gauche. Flèche étiquetée points d’écriture du service A à la base de données. Le service B réside en dehors de cette section à droite. Une flèche intitulée "lire" pointe vers la base de données. Un X rouge traverse cette flèche.

Cette approche conduit naturellement à la persistance polyglotte, ce qui signifie utiliser plusieurs technologies de stockage de données au sein d’une seule application. Un service peut avoir besoin des fonctionnalités de lecture de schéma d’une base de données de documents. Un autre service peut avoir besoin de l’intégrité référentielle qu’offre un système de gestion de base de données relationnelle (SGBDR). Chaque équipe peut choisir la meilleure option pour son service.

Note

Les services peuvent partager en toute sécurité le même serveur de base de données physique. Des problèmes se produisent lorsque les services partagent le même schéma, ou qu’ils lisent et écrivent dans le même ensemble de tables de base de données.

Défis

L’approche distribuée de la gestion des données présente plusieurs défis. D'abord, la redondance peut se produire dans les bases de données. Le même élément de données peut apparaître à plusieurs emplacements. Par exemple, les données peuvent être stockées dans le cadre d’une transaction, puis stockées ailleurs pour l’analytique, la création de rapports ou l’archivage. Les données en double ou partitionnée peuvent entraîner des problèmes d’intégrité et de cohérence des données. Lorsque les relations de données s’étendent sur plusieurs services, les techniques de gestion des données traditionnelles ne peuvent pas appliquer ces relations.

La modélisation traditionnelle des données suit la règle d’un seul fait dans un seul endroit. Chaque entité apparaît exactement une fois dans le schéma. D’autres entités peuvent le référencer, mais pas le dupliquer. L’avantage principal de l’approche traditionnelle est que les mises à jour se produisent à un seul endroit, ce qui empêche les problèmes de cohérence des données. Dans une architecture de microservices, vous devez prendre en compte la propagation des mises à jour entre les services et la gestion de la cohérence éventuelle lorsque les données apparaissent dans plusieurs emplacements sans cohérence forte.

Approches de gestion des données

Aucune approche unique ne fonctionne pour tous les cas. Tenez compte des instructions générales suivantes pour gérer les données dans une architecture de microservices :

  • Définissez le niveau de cohérence requis pour chaque composant et préférez la cohérence éventuelle si possible. Identifiez les zones du système où vous avez besoin d'une forte cohérence ou atomicité, ainsi que des transactions ACID (atomicité, cohérence, isolation, durabilité). Et identifier les zones où la cohérence éventuelle est acceptable. Pour plus d’informations, consultez Utiliser la conception basée sur un domaine tactique (DDD) pour les microservices.

  • Utilisez une seule source de vérité lorsque vous avez besoin d’une cohérence forte. Un service peut représenter la source de vérité d’une entité donnée et l’exposer via une API. D’autres services peuvent contenir leur propre copie des données, ou un sous-ensemble des données, qui sont finalement cohérents avec les données primaires, mais qui ne sont pas considérés comme la source de vérité. Par exemple, dans un système de commerce électronique qui a un service de commande client et un service de recommandation, le service de recommandation peut écouter les événements du service de commande. Toutefois, si un client demande un remboursement, le service de commande, et non le service de recommandation, a l’historique des transactions complet.

  • Appliquez des modèles de transaction pour maintenir la cohérence entre les services. Utilisez des modèles tels que le superviseur de l’agent planificateur et la transaction compensatoire pour assurer la cohérence des données entre plusieurs services. Pour éviter une défaillance partielle entre plusieurs services, vous devrez peut-être stocker une partie supplémentaire des données qui capture l’état d’une unité de travail qui s’étend sur plusieurs services. Par exemple, conservez un élément de travail sur une file d’attente durable pendant qu’une transaction en plusieurs étapes est en cours.

  • Stockez uniquement les données dont un service a besoin. Un service peut uniquement avoir besoin d’un sous-ensemble d’informations sur une entité de domaine. Par exemple, dans le contexte délimité de livraison, vous devez savoir quel client est lié à une livraison spécifique. Toutefois, vous n’avez pas besoin de l’adresse de facturation du client, car le contexte lié aux comptes gère ces informations. Une analyse de domaine minutieuse et une approche DDD peuvent appliquer ce principe.

  • Déterminez si vos services sont cohérents et faiblement couplés. Si deux services échangent continuellement des informations entre eux et créent des API chatteuse, vous devrez peut-être redessiner vos limites de service. Fusionnez les deux services ou refactorisez leurs fonctionnalités.

  • Utilisez un style d’architecture piloté par les événements. Dans ce style d’architecture, un service publie un événement lorsque des modifications apportées à ses modèles ou entités publics se produisent. D’autres services peuvent s’abonner à ces événements. Par exemple, un autre service peut utiliser les événements pour construire une vue matérialisée des données plus adaptées à l’interrogation.

    • Publiez un schéma pour les événements. Un service propriétaire d’événements doit publier un schéma pour automatiser la sérialisation et la désérialisation des événements. Cette approche évite un couplage étroit entre les éditeurs et les abonnés. Considérez le schéma JSON ou une infrastructure comme Protobuf ou Avro.

    • Réduisez les goulots d’étranglement évènementiels à grande échelle. À grande échelle, les événements peuvent devenir un goulot d’étranglement sur le système. Envisagez d’utiliser l’agrégation ou le traitement par lots pour réduire la charge totale.

Exemple : Choisir des magasins de données pour l’application de livraison de drone

Les articles précédents de cette série décrivent un service de livraison de drone comme exemple en cours d’exécution. Pour plus d’informations sur le scénario et l’architecture correspondante, consultez Concevoir une architecture de microservices.

Pour récapituler, cette application définit plusieurs microservices pour planifier les livraisons par drone. Lorsqu’un utilisateur planifie une nouvelle livraison, la demande du client inclut des informations sur la livraison, telles que les emplacements d’enlèvement et de dépôt, ainsi que sur le package, comme la taille et le poids. Ces informations définissent une unité de travail.

Les différents services principaux utilisent différentes parties des informations dans la requête et ont des profils de lecture et d’écriture différents.

Diagramme montrant les considérations relatives aux données.

Service de livraison

Le service de livraison stocke des informations sur chaque livraison actuellement planifiée ou en cours. Il écoute les événements des drones et suit l’état des livraisons en cours. Il envoie également des événements de domaine avec des mises à jour d’état de remise.

Les utilisateurs vérifient fréquemment l’état d’une livraison pendant qu’ils attendent leur package. Par conséquent, le service de livraison nécessite un magasin de données qui priorise le débit (lecture et écriture) au détriment du stockage à long terme. Le service de remise n’effectue pas de requêtes ou d’analyse complexes. Il récupère uniquement l’état le plus récent pour une livraison spécifique. L’équipe de service de livraison a choisi Azure Managed Redis pour ses performances élevées en lecture-écriture. Les informations stockées dans Azure Managed Redis sont de courte durée. Une fois la livraison terminée, le service d’historique de livraison devient le système d’enregistrement.

Service d’historique de livraison

Le service d’historique de livraison écoute les événements d’état de livraison du service de livraison. Il stocke ces données dans le stockage à long terme. Ces données historiques prennent en charge deux scénarios, chacun avec des exigences de stockage différentes.

Le premier scénario agrège les données pour l’analytique des données afin d’optimiser l’entreprise ou d’améliorer la qualité du service. Le service d’historique de livraison n’effectue pas l’analyse réelle des données. Il ingère et stocke uniquement les données. Pour ce scénario, le stockage doit être optimisé pour l’analyse des données sur des jeux de données volumineux et utiliser une approche de schéma en lecture pour prendre en charge différentes sources de données. Azure Data Lake Storage est adapté à ce scénario, car il s’agit d’un système de fichiers Apache Hadoop compatible avec hdFS (Hadoop Distributed File System). Elle est également paramétrée pour les performances des scénarios d’analytique des données.

Le deuxième scénario permet aux utilisateurs de rechercher l’historique d’une livraison une fois la remise terminée. Data Lake Storage ne prend pas en charge ce scénario. Pour des performances optimales, stockez les données de série chronologique dans Data Lake Storage dans les dossiers partitionnés par date. Toutefois, cette structure rend les recherches individuelles basées sur des ID inefficaces. Sauf si vous connaissez également l’horodatage, une recherche d’ID vous oblige à analyser l’intégralité de la collection. Pour résoudre ce problème, le service d’historique de livraison stocke également un sous-ensemble des données historiques dans Azure Cosmos DB pour une recherche plus rapide. Les enregistrements n’ont pas besoin de rester dans Azure Cosmos DB indéfiniment. Vous pouvez archiver les livraisons plus anciennes après une période spécifique, comme un mois, en exécutant un processus de traitement par lots occasionnel. L’archivage des données peut réduire les coûts d’Azure Cosmos DB et conserver les données disponibles pour les rapports historiques à partir de Data Lake Storage.

Pour plus d’informations, consultez Régler Data Lake Storage pour connaître les performances.

Service de colis

Le service de package stocke des informations sur tous les packages. Le magasin de données du service de package doit répondre aux exigences suivantes :

  • Stockage à long terme
  • Débit d’écriture élevé pour gérer un grand volume de packages
  • Requêtes simples par ID de package sans jointures complexes ou contraintes d’intégrité référentielle

Les données du package ne sont pas relationnelles. Par conséquent, une base de données orientée document fonctionne bien. Azure DocumentDB peut atteindre un débit élevé à l’aide de collections partitionnées. L'équipe du service de gestion des paquets est familiarisée avec la pile technologique MEAN, qui inclut MongoDB, Express.js, AngularJS et Node.js, de sorte qu’elle choisit d’implémenter Azure DocumentDB. Ce choix leur permet d’utiliser leur expérience MongoDB existante tout en obtenant les avantages d’un service Azure entièrement managé hautes performances.