mardi 12 janvier 2021

Une base de données par microservice ou une base de données partagée?

Quand on développe une application à base de microservices, on doit s’assurer que chaque microservice a toutes les données dont il a besoin pour traiter toutes les requêtes des clients.

Imaginons que l’on veut développer une application de boutique en ligne utilisant le modèle d’architecture Microservices. La plupart des services doivent conserver les données dans une sorte de base de données. Par exemple, le service de commande stocke des informations sur les commandes et le service client stocke des informations sur les clients.

Le problème peut être posé en ces termes: quelle approche adopter pour les bases de données, pour une application à base de microservices, en tenant compte des contraintes et exigences suivantes:

  • Les services doivent être faiblement couplés afin d’être développés, déployés et mis à l'échelle indépendamment
  • Certaines transactions d’affaires doivent appliquer des invariants couvrant plusieurs services, par exemple,  dans l’application du commerce en ligne, le cas d'utilisation « Passer une commande » doit vérifier qu'une nouvelle commande ne dépassera pas la limite de crédit du client. D’autres transactions doivent mettre à jour les données dispersées dans plusieurs services.
  • Certaines transactions d’affaires doivent interroger des données appartenant à plusieurs services. Par exemple, le cas d’utilisation « Afficher le crédit disponible d’un client »  doit interroger le service Client pour trouver la limite de crédit et le service Commande pour calculer le montant total des commandes ouvertes par le client.
  • Certaines requêtes doivent joindre des données appartenant à plusieurs services. Par exemple, trouver des clients dans une région particulière et leurs commandes récentes nécessite une jonction entre les clients et les commandes.
  • Les bases de données doivent parfois être répliquées et partitionnées pour optimiser certaines requêtes
  • Certains services ont des exigences de stockage de données spécifiques. Pour certains services, une base de données relationnelle est le meilleur choix. D'autres services peuvent avoir besoin d'une base de données NoSQL comme MongoDB par exemple, qui est plus adapté pour stocker des données complexes et non structurées, ou Neo4J, qui est conçue pour stocker et interroger efficacement les données graphiques.

Dans les milieux des microservices, il existe 2 approches de solution à ce problème

La première approche est le modèle base de données par service.      

Dans cette approche, chaque microservice gère ses propres données. Cela implique qu'un microservice ne peut pas accéder directement aux données d’un autre. La communication ou l'échange de données n’est alors possible qu’à travers un ensemble d'API bien définies.

Contrairement aux apparences, implémenter ce modèle est loin d’être facile.

En effet, si les contextes sont mal délimités, comme c’est souvent le cas en général, les microservices auront besoin de données des uns les autres pour implémenter leur logique d’affaires, ce qui va conduire à des interactions de type spaghetti entre différents services de l’application.

Le succès de ce modèle dépend d’une définition efficace des contextes délimités du domaine d’affaire de l’application. Ce découpage est relativement plus facile à faire pour une nouvelle application. Mais pour les gros systèmes monolithiques que l’on est en train de migrer vers les microservices, c'est plus compliqué.

D'autres défis incluent la mise en œuvre des transactions qui impliquent plusieurs microservices et la mise en œuvre des requêtes qui manipulent des données provenant de deux ou trois contextes délimités différents.

Si la mise en œuvre de ce pattern est faite proprement, le principal avantage est un couplage lâche entre les microservices.  En outre, on peut mettre à jour ou faire évoluer les microservices individuellement, et les équipes de développeurs ont aussi la liberté de choisir une solution de base de données spécifique pour un microservice donné.

La deuxième approche de solution est le modèle « base de données partagée ».

Une base de données partagée peut être une option viable si les défis liés à la base de données par service deviennent trop difficiles à gérer. Il s'agit d'une option peu risquée pour mieux regrouper les données qui étaient dans le monolithe dans le cas d’une migration vers les microservices. Elle aide également à implémenter facilement les transactions dites ACID, c’est-à-dire les transactions Atomiques, Cohérentes, Isolées et Durables. Notons que pour implémenter les transactions ACID dans l’approche précédente, le pattern SAGA est souvent utilisé.

Le modèle « base de données partagée » tente de résoudre les mêmes problèmes que le premier, mais en adoptant une approche un peu moins radicale qui est l’utilisation d’une base de données partagée accessible par plusieurs microservices.

Il est important de limiter la base de données commune à deux ou trois microservices, pas plus. Sinon, faire évoluer ces services sera un gros problème à l’avenir.

Cependant, cette approche supprime la plupart des avantages des microservices. Les développeurs de toutes les équipes doivent coordonner les modifications de schéma des tables. Il peut également y avoir des conflits d'exécution lorsque plusieurs services tentent d'accéder aux mêmes ressources de base de données.

Dans l'ensemble, cette approche peut faire plus de mal que de bien à long terme.

Certains praticiens la considèrent d’ailleurs comme un anti-pattern.


Pour apprendre davantage sur les patterns 'base de données' pour la conception des microservices, reportez-vous à ce cours sur la plateforme Udemy : Le patterns de conception des microservices

Pour comprendre le processus de conception d'une architecture de microservices, reportez-vous à ce cours sur la plateforme Udemy : Conception d’une architecture de microservices


Références:


Aucun commentaire:

Enregistrer un commentaire