web-dev-qa-db-fra.com

Microservices et jointures de bases de données

Pour les personnes qui scindent des applications monolithiques en microservices, comment gérez-vous le mystère de la fragmentation de la base de données? Les applications typiques sur lesquelles j'ai travaillé font beaucoup d'intégration de bases de données pour des raisons de performance et de simplicité.

Si vous avez deux tables qui sont logiquement distinctes (contextes liés si vous voulez) mais que vous effectuez souvent un traitement agrégé sur de grands volumes de ces données, dans le monolithe, vous éviterez probablement l'orientation objet et vous utiliserez plutôt 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 au niveau de vos applications.

Comment justifiez-vous le fractionnement de ces données en microservices où, vraisemblablement, vous devrez «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 consacré à la scission du monolithe, il donne un exemple de "Breaking Foreign Key Relationships" dans lequel il reconnaît qu'une jointure via une API va être plus lente. votre application est quand même assez rapide, est-il important qu'elle soit plus lente 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?

71
Martin Bayly
  • Lorsque les performances ou la latence importent peu (oui, nous n'en avons pas toujours besoin.), Il n’est pas inutile d’utiliser de simples API RESTful Pour interroger des données supplémentaires dont vous avez besoin. Si vous devez effectuer plusieurs appels Vers différents microservices et renvoyer un résultat, vous pouvez utiliser API Gateway pattern.

  • La redondance dans persistance polyglotte environnements est parfaitement acceptable. Par exemple, vous pouvez utiliser la file d'attente de messagerie pour vos microservices et envoyer des événements "update" chaque fois que vous modifiez quelque chose. D'autres microservices écoutent les événements requis et enregistrent 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 tels que Redis ou Memcached pour éviter d'interroger trop souvent d'autres bases de données. 

16
sap1ens

Il est normal que les services aient des copies répliquées en lecture seule de certaines données de référence provenant d'autres services.

Étant donné que, lorsque je tente de reformuler une base de données monolithique en microservices (par opposition à une 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 de la table/strucutre sans casser d’autres applications.

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

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

5
mcintyre321

CQRS --- Le modèle d'agrégation de requêtes de commande est la réponse à cette question, selon Chris Richardson . Laissez chaque microservice mettre à jour son propre modèle de données et génère les événements qui mettront à jour la vue matérialisée contenant les données de jointure requises des microservices précédents. Ce MV peut être n'importe quelle base de données NoSql, Redis ou elasticsearch optimisée pour les requêtes. Cette technique conduit à une cohérence éventuelle qui n’est certainement pas mauvaise et évite les jointures en temps réel des applications . J'espère que cela répond.

3
Praful

Je séparerais les solutions pour le domaine d’utilisation, disons opérationnelle et de reporting.

Pour les microservices qui fonctionnent pour fournir des données à des formulaires uniques qui nécessitent des données provenant d’autres microservices (c’est le cas opérationnel), je pense que l’utilisation de jointures API est la solution. 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 lorsque vous devez faire de grandes requêtes sur une grande quantité de données pour faire des agrégations, etc. (le cas du 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 microservice. Sur cette base de données partagée, vous pouvez continuer à utiliser vos procédures stockées, ce qui vous évitera des efforts et vous aidera à optimiser la base de données.

1
Jaro64

Dans Microservices, vous créez des diff. lire les modèles, donc par exemple: si vous avez deux diff. contexte lié et si quelqu'un souhaite effectuer une recherche sur les deux données, il doit écouter les événements des deux contextes liés et créer une vue spécifique pour l'application.

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

0
techagrammer