ninog - Fotolia
Appréhender l’architecture de gestion de données avec les microservices
Les microservices ont des besoins de gestion de données qui ne sont pas comparables à ceux des autres architectures logicielles. Pour réussir, vous aurez besoin d’un ensemble approprié de connaissances, de mécanismes et de principes de conception.
Cela peut paraître une évidence, mais les microservices ne sont pas des monolithes. Ils ne sont pas non plus exclusivement des applications, basées sur des containers, même si un grand nombre d’équipes IT combinent ces deux technologies. Les microservices sont très différents de ce à quoi la plupart des architectes sont habitués. Dès lors, l’accès aux données nécessite une nouvelle approche et un ensemble de mécanismes, pour conserver une forme de stabilité et les fonctionnalités.
Pour former une stratégie efficace de gestion des données avec des microservices, il est essentiel que les développeurs suivent des principes appropriés, mettent en place les bons processus et les bons modèles. Examinons de plus près cet obstacle et les mesures à prendre.
Comment les microservices affectent-ils la gestion des bases de données ?
Les containers ont laissé entrevoir des problèmes de gestion des données qui affligent les microservices. Tout comme les applications containérisées sont déployées avec leur propre base ou table de données, les microservices individuels ont besoin de leur data store dédié, pour s’adapter de manière indépendante et se remplacer sans provoquer de casse.
Cette situation entraîne trois difficultés :
- Les services doivent rester stateless, ce qui signifie qu’un service ne doit jamais stocker en son sein des informations sur l’état, y compris celles concernant l’accès aux données ou les cycles de mise à jour.
- Dès lors, il faut s’occuper d’un SGBD consacré aux informations externalisées.
- Les applications reposant sur les microservices dépendent souvent de plusieurs bases de données, ce qui les rend sensibles aux problèmes de cohérence de l’information.
Pour résoudre ces trois problèmes, nous allons d’abord passer en revue les principes fondamentaux que tous les architectes devraient suivre.
Petits rappels des attributs ACID
Optimiser la gestion de données des applications basées sur des microservices nécessite d’adopter l’architecture et la technologie adéquates. Il ne s’agit pas simplement de choisir un type de base de données plutôt qu’un autre, ou de la placer dans un container externe. Il convient de prendre en compte un ensemble d’attributs bien connus sous l’acronyme ACID : atomicité, cohérence, isolation et durabilité.
- L’atomicité impose de ne jamais laisser les opérations de base de données partiellement achevées. Ces opérations ne doivent pas être analysées ou divisées en petits groupes de tâches indépendantes.
- La cohérence signifie que la base de données ne peut enfreindre les règles qui régissent la manière dont elle gère les défaillances. Par exemple, si une modification en plusieurs étapes échoue à mi-chemin, l’opération doit être relancée pour éviter de conserver des informations inexactes.
- L’isolation répond au principe selon lequel chaque opération de la base doit fonctionner sans dépendre des autres ni les affecter. En respectant cette règle, le data store supporte plusieurs requêtes concurrentes sans que ses propres altérations n’impactent ces opérations.
- La durabilité fait référence à la résilience d’une base de données. Les architectes doivent toujours prévoir les pannes et les perturbations en mettant en œuvre les mécanismes de retour en arrière appropriés, en restant attentifs aux couplages et en testant régulièrement la réaction de ce SGBD.
Maintenant que nous avons revu ces principes, nous pouvons évaluer les approches et les designs qui peuvent aider à maintenir la cohérence des données dans une architecture de microservices.
Les bases de données NoSQL aident, mais ne suffisent pas
Les systèmes de gestion de bases de données relationnelles (SGBDR) et d’autres architectures conventionnelles entraînent une surcharge liée à l’accès aux données. Dans une application monolithique, cela pose rarement de difficulté, car un processus unique permet de récupérer un enregistrement resté en mémoire jusqu’à la fin d’un traitement. Cependant, comme les principes régissant les microservices interdisent de stocker des données d’état de la même manière, chacun d’eux doit bénéficier d’un accès à la base. Tout à coup, la surcharge évoquée plus tôt pose problème.
L’utilisation des SGBD NoSQL, qui s’appuient eux sur des paires de clés-valeurs ou sur des objets peut aider, car ils transmettent le fichier entier qu’ils créent à tous les services en même temps. Toutefois, égarer cet objet pourrait signifier perdre l’ensemble des transactions de votre application avec lui. Dès lors, le modèle NoSQL ne permet pas de franchir complètement cet obstacle.
Pour y parvenir, nous devons nous tourner vers certains modèles d’architecture qui traitent spécifiquement de la relation entre les microservices et les bases de données. Voici quatre schémas importants que tous les développeurs devraient connaître.
Les modèles fondamentaux pour coupler microservices et bases de données
Base de données par service. Ce modèle convient lorsque les architectes peuvent facilement parser les services en fonction des exigences de la base de données, ainsi que gérer les flux de transactions à l’aide d’un processus de contrôle. Les problèmes ACID sont ici minimes, car aucun microservice ne partage réellement un data store. Malheureusement, du fait que certains services sont plus à l’aise avec un type de SGBD (SQL ou NoSQL), il peut être difficile d’orchestrer les requêtes pour les relier (au besoin).
Base de données partagée. Ce pattern porte bien son nom : plusieurs microservices utilisent un seul SGBD abstrait. Un nombre important d’opérations simultanées peut provoquer des conflits dans cette approche, de sorte que le SGBD doit gérer lui-même et avec diligence la conformité aux principes ACID. Plusieurs SGBDR semblent adaptés, mais il existe un autre modèle qui pourrait mieux convenir à ce mécanisme de partage intense d’informations/mises à jour.
Le pattern SAGA. Ce modèle de conception génère une série de transactions locales qui fusionnent pour produire un seul service. Si l’une des transactions locales échoue en raison de tests ou de politiques internes, l’approche saga garantit que la base de données peut retirer la série de transactions à l’aide de déclencheurs d’événements orchestrés. Chaque microservice effectue alors l’une des deux opérations ci-dessous. Soit il lance une transaction locale pour exécuter une tâche et passer à la suivante, soit il engendre les transactions réelles qui constitueront la chaîne de processus. Cela aide à maintenir la cohérence des données. En revanche, la programmation des logiques conditionnelles rend la chose un peu plus complexe.
Le modèle event sourcing. De nombreux développeurs privilégient ce mode, consistant à utiliser un élément statique qui capture et stocke de manière persistante, un enregistrement des transactions basées sur des événements. Lorsqu’un microservice accède à cet élément, il établit un état en « rejouant » l’enregistrement pour le service. Les développeurs peuvent également modifier cette liste d’événements selon les besoins.
Ces quatre architectures sont les plus plébiscitées, mais il existe quelques autres méthodes pertinentes pour préserver la cohérence des données. Par exemple, le modèle Command and Query Responsibility Segregation (CQRS) maintient une copie en lecture seule d’un élément de donnée. Le pattern API Composition consiste, lui, à utiliser un broker API pour construire une version d’un objet de données en mémoire à partir de SGBD alloué par microservice.