web-dev-qa-db-fra.com

Comment garder DB synchronisé lors de l'utilisation de l'architecture de microservices?

Je suis sur le point d'apprendre comment fonctionne l'architecture des microservices. Jusqu'à présent, je n'ai pas compris que chaque microservice a besoin de sa propre base de données, ce qui est logique.

Disons donc que nous avons un microservice client qui est chargé de créer un client et de renvoyer une liste de clients. Le service aura sa propre base de données client.

Disons que nous avons une charge très élevée sur cet ervice, nous avons donc choisi de passer à l'échelle 20x.

Så nous avons 20 microservices et chacun a sa propre base de données, et tous les services sont derrière un équilibreur de charge.

Désormais, un client souhaite créer un client, l'équilibreur de charge envoie la demande du client au service 9/20 et le client est créé.

A la demande suivante, le même client veut être sûr que le client est créé et souhaite voir la liste des clients, sur la demande que LB lui envoie au service 11/20.

Maintenant, comment puis-je m'assurer que le service 9/20 a synchronisé le client nouvellement créé avec la base de données du service 11/20?

Dans MSSQL, il existe des fonctionnalités pour maintenir la synchronisation de la base de données avant de permettre la validation initiale, pour enregistrer d'abord les données dans toutes les autres bases de données, mais cette approche posera des problèmes à long terme, car plus il y a de services, plus la durée est longue prendre pour faire un commit?

21
Timsen

chaque microservice a besoin de sa propre base de données

Une base de données distincte par microservice n'est pas une condition préalable (ni une exigence, vraiment).

Vous pouvez avoir autant de microservices que vous voulez travailler sur la même base de données, mais utiliser des schémas différents par exemple.

Le contexte délimité d'un microservice doit être la frontière.

Disons que nous avons une charge très élevée sur ce service, nous avons donc choisi de passer à l'échelle 20x.

La mise à l'échelle vers des instances (X) du même microservice ne signifie pas nécessairement avoir une base de données distincte pour chaque instance de ce même service.

La plupart des bases de données sont conçues en tenant compte des connexions simultanées, des utilisateurs et des transactions. une seule instance de base de données (avec une concurrence optimiste) peut gérer des centaines (sinon des milliers) de connexions simultanées avec élégance.

Si vous avez explicitement choisi d'avoir une base de données distincte par instance du même service, vous devrez synchroniser ces bases de données. et, très probablement, la cohérence des données en souffrira.

Voici quelques suggestions:

  • utiliser une seule base de données par microservice (et non par instance) quel que soit le nombre d'instances qui l'utilisent. Et ne considérez une base de données par instance que lorsque vous êtes sûr qu'une seule base de données ne peut pas gérer la charge.

  • Utilisez une couche de cache partagée au-dessus de la base de données (peut-être redis cache)

  • Utilisez un cluster de bases de données pour gérer la charge/disponibilité élevée des bases de données.

12
Bishoy

Bien que l'utilisation de la même base de données pour plusieurs services soit possible, elle doit être évitée car elle créera un couplage entre les services plus élevé que souhaité. Par exemple. un temps d'arrêt de la base de données affectera tous les services avec partage, mais un seul si chaque service en possède un.

Pour éviter un "monolithe distribué" de services qui effectuent des appels synchrones entre eux (par exemple en utilisant REST), vous pouvez travailler avec une approche basée sur le streaming. Chaque service publiera un événement de modification chaque fois que ses données changent, et d'autres services peuvent s'abonner à ces flux. Ainsi, ils peuvent réagir aux changements de données qui les concernent, par exemple en stockant une version locale des données (dans une représentation adaptée à leurs besoins, par exemple uniquement les colonnes qui les intéressent) dans leur propre base de données. De cette façon, ils peuvent fournir leurs fonctionnalités, même si d'autres services ne sont pas disponibles pendant un certain temps. Naturellement, une telle architecture utilise une sémantique de cohérence éventuelle, mais c'est généralement inévitable dans les systèmes distribués de toute façon.

Une façon de configurer de tels flux de données est de modifier le CDC de capture de données, qui suivra les fichiers journaux des bases de données (par exemple, le journal des connexions dans MySQL) et publiera les événements correspondants pour chaque INSERT, UPDATE et DELETE. Un outil CDC open source est Debezium qui est livré avec des connecteurs pour MySQL, Postgres, MongoDB ainsi que (en cours de réalisation à partir de maintenant) Oracle et SQL Server. Il peut être utilisé avec Apache Kafka comme backbone de streaming ou comme bibliothèque au sein de vos applications Java, vous permettant de diffuser les modifications de données dans d'autres couches de streaming telles que Pulsar ou Kinesis avec juste un peu de code. Un avantage intéressant d'utiliser des sujets persistants pour les événements de changement, par exemple avec Kafka, est que de nouveaux services peuvent apparaître et relire l'intégralité du flux de changements (en fonction de la politique de rétention du sujet) ou simplement obtenir l'état actuel de chaque enregistrement pour effectuer une première graine de leur base de données locale.

(Avertissement: je suis le responsable de Debezium)

3
Gunnar

Cela peut être réalisé en utilisant le modèle de conception CQRS, qui est la séparation de la création et de la visualisation de l'entité en suivant le paradigme asynchrone.

Pendant la création, nous poussons la persistance d'entité vers Kafka/RabbitMQ et la poussons vers la base de données de manière asynchrone. Des vues matérialisées peuvent être créées sur la base de données, ce qui accélère la récupération.

0
DevEmani