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?
la source
Réponses:
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.
la source
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
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.
la source
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.
la source
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.
la source
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.
la source