Microservices et jointures de bases de données


112

Pour les personnes qui divisent des applications monolithiques en microservices, comment gérez-vous le connundrum de la séparation de la base de données. Les applications typiques sur lesquelles j'ai travaillé font beaucoup d'intégration de base de données pour des raisons de performances et de simplicité.

Si vous avez deux tables qui sont logiquement distinctes (contextes limités si vous voulez) mais que vous effectuez souvent un traitement agrégé sur un grand volume de ces données, alors dans le monolithe, vous êtes plus que susceptible d'éviter l'orientation des objets et utilisez à la place la norme de votre base de données. JOIN pour traiter les données de la base de données avant de renvoyer la vue agrégée à votre niveau d'application.

Comment justifiez-vous la division de ces données en microservices où vous devrez vraisemblablement «joindre» les données via une API plutôt que dans la base de données.

J'ai lu le livre Microservices de Sam Newman et dans le chapitre sur la division du monolithe, il donne un exemple de "Breaking Foreign Key Relationships" où il reconnaît que faire une jointure à travers une API va être plus lent - mais il continue en disant si votre application est de toute façon assez rapide, est-ce que c'est plus lent qu'avant?

Cela semble un peu désinvolte? Quelles sont les expériences des gens? Quelles techniques avez-vous utilisées pour que les jointures d'API fonctionnent de manière acceptable?


2
Bonne question, je rencontre le même problème et j'ai fini par avoir une vue matérialisée et faire des jointures là-dessus. Je n'aime pas ça, mais je suppose que ça va être un défi avec Micro Services. Il n'y a pas de bonne façon de faire cela, c'est juste un choix de design à faire. Je sais que beaucoup de gens disent que nous pouvons avoir une vue matérialisée, mais les réponses agrégées deviennent un problème. Faites-moi savoir si vous avez trouvé quelque chose de mieux.
PavanSandeep le

Je sais que c'est vieux, mais est-ce quelque chose que graphql résout? J'examine également cela pour une migration segmentée, et il semble que graphql soit le moyen de rendre cela transparent.
themightybun

À un moment donné, vous devriez réaliser qu'être dogmatique n'est pas la voie à suivre. GraphQL est un bon exemple d'agrégation en dehors de la source de données et cela fonctionne généralement très bien.
Christian Ivicevic

Réponses:


26
  • Lorsque les performances ou la latence n'ont pas trop d'importance (oui, nous n'en avons pas toujours besoin), il est parfaitement normal d'utiliser de simples API RESTful pour interroger les données supplémentaires dont vous avez besoin. Si vous devez effectuer plusieurs appels à différents microservices et renvoyer un résultat, vous pouvez utiliser le modèle API Gateway .

  • Il est parfaitement normal d'avoir une redondance dans les environnements de persistance Polyglot . Par exemple, vous pouvez utiliser la file d'attente de messagerie pour vos microservices et envoyer des événements de «mise à jour» chaque fois que vous modifiez quelque chose. D'autres microservices écouteront les événements requis et enregistreront les données localement. Ainsi, au lieu d'interroger, vous conservez toutes les données requises dans un stockage approprié pour un microservice spécifique.

  • N'oubliez pas non plus la mise en cache :) Vous pouvez utiliser des outils comme Redis ou Memcached pour éviter d'interroger trop souvent d'autres bases de données.


25
Toutes les bonnes suggestions, mais j'ai toujours du mal à rationaliser, peut-être parce que nous sommes tellement habitués à faire beaucoup de traitement dans la base de données. Notre application actuelle comporte des procédures stockées complexes qui traitent de gros volumes de données, puis renvoient un petit ensemble de résultats. Dans une architecture de microservices, je pense que ces entités devraient être divisées en différents contextes délimités. Nous savons que l'approche actuelle est laide, mais il est difficile de justifier de ramener toutes les données au niveau de l'application pour les traiter. Peut-être que plus de dénormalisation ou de pré-calcul des vues agrégées serait utile.
Martin Bayly

1
Oui je vois. L'approche des microservices n'est pas pour tout le monde et vous devez l'appliquer avec soin. Vous pouvez probablement commencer par de plus petits changements.
sap1ens

Probablement les programmeurs StackExchange auraient été un meilleur endroit pour poser cette question: programmers.stackexchange.com/questions/279409/… et d'autres questions étiquetées microservices programmers.stackexchange.com/questions/tagged/microservices
Martin Bayly

9

Les services peuvent avoir des copies répliquées en lecture seule de certaines données de référence à partir d'autres services.

Étant donné que, en essayant de refactoriser une base de données monolithique en microservices (par opposition à la réécriture), je voudrais

  • créer un schéma de base de données pour le service
  • créer des * vues ** versionnées dans ce schéma pour exposer les données de ce schéma à d'autres services
  • faire des jointures contre ces vues en lecture seule

Cela vous permettra de modifier indépendamment les données / strucutre de la table sans casser les autres applications.

Plutôt que d'utiliser des vues, je pourrais également envisager d'utiliser des déclencheurs pour répliquer les données d'un schéma à un autre.

Ce serait un progrès progressif dans la bonne direction, établissant les coutures de vos composants, et un passage à REST peut être fait plus tard.

* les vues peuvent être étendues. Si une modification avec rupture est requise, créez une version 2 de la même vue et supprimez l'ancienne version lorsqu'elle n'est plus nécessaire. ** ou Table-Valued-Functions, ou Sprocs.


5

CQRS --- Le modèle d'agrégation de requêtes de commande est la réponse à ce problème selon Chris Richardson. Laisser chaque microservice mettre à jour son propre modèle de données et générer les événements qui mettront à jour la vue matérialisée ayant les données de jointure requises des microservices précédents. Cette technique conduit à une cohérence éventuelle qui n'est certainement pas mauvaise et évite les jointures côté application en temps réel. J'espère que cela répond.


2

Je séparerais les solutions pour le domaine d'utilisation, disons opérationnel et reporting.

Pour les microservices qui fonctionnent pour fournir des données pour des formulaires uniques qui ont besoin de données provenant d'autres microservices (c'est le cas opérationnel), je pense que l'utilisation de jointures API est la voie à suivre. Vous n'irez pas pour de grandes quantités de données, vous pouvez faire l'intégration de données dans le service.

L'autre cas est celui où vous devez effectuer de grosses requêtes sur une grande quantité de données pour effectuer des agrégations, etc. (le cas de rapport). Pour ce besoin, je penserais à maintenir une base de données partagée - similaire à votre schéma d'origine et à la mettre à jour avec les événements de vos bases de données de microservices. Sur cette base de données partagée, vous pouvez continuer à utiliser vos procédures stockées, ce qui vous fera économiser vos efforts et prend en charge les optimisations de la base de données.


1

Dans Microservices, vous créez des diff. lire les modèles, donc par exemple: si vous avez deux diff. contexte borné et quelqu'un veut rechercher à la fois les données, alors quelqu'un doit écouter les événements des deux contextes bornés et créer une vue spécifique à l'application.

Dans ce cas, il y aura plus d'espace nécessaire, mais aucune jointure ne sera nécessaire et aucune jointure.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.