Microservices et jointures de bases de données

Pour les personnes qui divisent des applications monolithiques en microservices, comment gérez-vous le problème de la séparation de la firebase database? Les applications typiques sur lesquelles j’ai travaillé font beaucoup d’intégration de bases de données pour des raisons de performances et de simplicité.

Si vous avez deux tables qui sont logiquement distinctes (les contextes bornés si vous voulez) mais que vous effectuez souvent le traitement d’agrégat sur de gros volumes de ces données, alors il est plus que probable que le monolithe évite l’orientation de l’object. Fonction JOIN pour traiter les données de la firebase database 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 probablement joindre les données via une API plutôt que dans la firebase database.

J’ai lu le livre de Sam Newman sur les microservices et dans le chapitre sur la division du monolithe, il donne un exemple de «briser les relations clés étrangères» où il reconnaît que se joindre à une API sera plus lent. votre application est assez rapide quand même, 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?

    • Lorsque les performances ou la latence ne sont pas trop importantes (oui, nous n’en avons pas toujours besoin), il est parfaitement recommandé d’utiliser des API RESTful simples pour interroger les 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 le modèle API Gateway .

    • Il est parfaitement correct d’avoir une redondance dans les environnements de persistance Polyglot . Par exemple, vous pouvez utiliser une queue de messagerie pour vos microservices et envoyer des événements de «mise à jour» chaque fois que vous modifiez quelque chose. D’autres microservices écoutent les événements requirejs et enregistrent les données localement. Ainsi, au lieu d’interroger, conservez toutes les données requirejses 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.

    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, en essayant de refactoriser une firebase database monolithique en microservices (par opposition à réécrire), je

    • créer un schéma de firebase database 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 également envisager d’utiliser des déclencheurs pour répliquer des données d’un schéma à un autre.

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

    CQRS — Le modèle d’agrégation de requêtes est la réponse à Chris Richardson. Laissez chaque microservice mettre à jour son propre modèle de données et générez les événements qui mettront à jour la vue matérialisée ayant les données de jointure requirejses provenant de microservices antérieurs. Ce MV pourrait être n’importe quelle firebase database NoSql, 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.

    Dans Microservices, vous créez un diff. lire des modèles, donc par exemple: si vous avez deux diff. contexte borné et quelqu’un veut chercher à la fois sur les données alors quelqu’un doit écouter les événements à la fois du contexte délimité 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.

    Je séparerais les solutions pour le domaine d’utilisation, disons les opérations et les rapports.

    Pour les microservices qui fournissent des données pour des formulaires uniques nécessitant des données provenant d’autres microservices (c’est le cas opérationnel), je pense que l’utilisation des jointures API est la solution. Vous n’allez pas chercher de grandes quantités de données, vous pouvez faire de l’intégration de données dans le service.

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