Il n'y a pas de solution claire car cela dépend entièrement de votre contexte - en particulier, selon les dimensions que votre système est censé évoluer et quels sont vos problèmes réels. La base de données est-elle vraiment votre goulot d'étranglement?
Cette réponse (malheureusement assez longue) se lira un peu comme «les microservices sont mauvais, des monolithes à vie!», Mais ce n'est pas mon intention. Mon point est que les microservices et les bases de données distribuées peuvent résoudre divers problèmes, mais non sans avoir certains problèmes qui leur sont propres. Afin de présenter un argument solide pour votre architecture, vous devez montrer que ces problèmes ne s'appliquent pas, peuvent être atténués et que cette architecture est le meilleur choix pour les besoins de votre entreprise.
Les données distribuées sont difficiles.
La même flexibilité qui permet une meilleure mise à l'échelle est le revers des garanties plus faibles. En particulier, les systèmes distribués sont beaucoup plus difficiles à raisonner.
Les mises à jour atomiques, les transactions, la cohérence / l'intégrité référentielle et la durabilité sont extrêmement précieuses et ne doivent pas être abandonnées précipitamment. Il ne sert à rien d'avoir des données si elles sont incomplètes, obsolètes ou carrément erronées. Lorsque ACID est une exigence commerciale mais que vous utilisez une technologie de base de données qui ne peut pas l'offrir immédiatement (par exemple, de nombreuses bases de données NoSQL ou une architecture DB-par-microservice), votre application doit combler le vide et fournir ces garanties.
Ce n'est pas impossible à faire, mais difficile à faire. Très délicat. Surtout dans un environnement distribué où il y a plusieurs écrivains dans chaque base de données. Cette difficulté se traduit par un risque élevé de bogues, pouvant inclure des données perdues, des données incohérentes, etc.
Par exemple, pensez à lire les analyses Jepsen de systèmes de bases de données distribuées bien connus , en commençant peut-être par l' analyse de Cassandra . Je ne comprends pas la moitié de cette analyse, mais le TL; DR est que les systèmes distribués sont si difficiles que même les projets leaders de l'industrie se trompent parfois, d'une manière qui peut sembler évidente avec le recul.
Les systèmes distribués impliquent également un effort de développement plus important. Dans une certaine mesure, il y a un compromis direct entre les coûts de développement ou la perte d'argent sur du matériel plus robuste.
Exemple: suspendre des références
En pratique, vous ne devriez pas regarder l'informatique mais les besoins de votre entreprise pour voir si et comment l'ACID peut être assoupli. Par exemple, de nombreuses relations avec des clés étrangères peuvent ne pas être aussi importantes qu'elles le semblent. Considérons une relation produit - catégorie n: m. Dans un SGBDR, nous pourrions utiliser une contrainte de clé étrangère afin que seuls les produits existants et les catégories existantes puissent faire partie de cette relation. Que se passe-t-il si nous introduisons des services de produits et de catégories distincts et qu'un produit ou une catégorie est supprimé?
Dans ce cas, cela pourrait ne pas être un gros problème et nous pouvons écrire notre application afin qu'elle filtre tous les produits ou catégories qui n'existent plus. Mais il y a des compromis!
Notez que cela peut nécessiter un niveau d'application JOIN
sur plusieurs bases de données / microservices, ce qui déplace simplement le traitement du serveur de base de données vers votre application. Cela augmente la charge totale et doit déplacer des données supplémentaires à travers le réseau.
Cela peut gâcher la pagination. Par exemple, vous demandez les 25 prochains produits d'une catégorie et filtrez les produits indisponibles de cette réponse. Votre application affiche désormais 23 produits. En théorie, une page avec zéro produit serait également possible!
Vous souhaiterez parfois exécuter un script qui nettoie les références pendantes, soit après chaque modification pertinente, soit à intervalles réguliers. Notez que ces scripts sont assez chers car ils doivent demander chaque produit / catégorie à la base de données / microservice de support pour voir s'il existe toujours.
Cela devrait être évident, mais pour plus de clarté: ne réutilisez pas les identifiants. Les ID de style à incrémentation automatique peuvent être corrects ou non. Les GUID ou les hachages vous offrent plus de flexibilité, par exemple en pouvant attribuer un ID avant que l'élément ne soit inséré dans une base de données.
Exemple: commandes simultanées
Considérons plutôt une relation produit - commande. Qu'advient-il d'une commande si un produit est supprimé ou modifié? Ok, nous pouvons simplement copier les données produit pertinentes dans l'entrée de commande pour les garder disponibles - échange d'espace disque pour plus de simplicité. Mais que se passe-t-il si le prix du produit change ou si le produit devient indisponible juste avant la commande de ce produit? Dans un système distribué, les effets prennent du temps à se propager et la commande passera probablement par des données obsolètes.
Encore une fois, la façon d'aborder cela dépend des besoins de votre entreprise. Peut-être que la commande obsolète est acceptable, et vous pouvez plus tard annuler la commande si elle ne peut pas être exécutée.
Mais ce n'est peut-être pas une option, par exemple pour les paramètres hautement concurrents. Considérez 3000 personnes se précipitant pour acheter des billets de concert dans les 10 premières secondes, et supposons qu'un changement de disponibilité nécessitera 10 ms pour se propager. Quelle est la probabilité de vendre le dernier billet à plusieurs personnes? Cela dépend de la façon dont ces collisions sont gérées, mais en utilisant une distribution de Poisson avec λ = 3000 / (10s / 10ms) = 3
nous avons une P(k > 1) = 1 - P(k = 0) - P(k = 1) = 80%
chance de collision par intervalle de 10 ms. Que la vente et l'annulation ultérieure de la majorité de vos commandes soient possibles sans commettre de fraude pourrait conduire à une conversation intéressante avec votre service juridique.
Le pragmatisme signifie choisir les meilleures fonctionnalités.
La bonne nouvelle est que vous n'avez pas besoin de passer à un modèle de base de données distribuée, si ce n'est pas requis autrement. Personne ne révoquera votre adhésion au Microservice Club si vous ne faites pas les microservices «correctement», car il n'y a pas un tel club - et il n'y a pas de véritable moyen de créer des microservices.
Le pragmatisme l'emporte à chaque fois, alors mélangez et associez différentes approches pour résoudre votre problème. Cela pourrait même signifier des microservices avec une base de données centralisée. Vraiment, ne passez pas par la douleur des bases de données distribuées si vous n'êtes pas obligé.
Vous pouvez évoluer sans microservices.
Les microservices présentent deux avantages majeurs:
- L'avantage organisationnel qu'ils peuvent être développés et déployés indépendamment par des équipes distinctes (ce qui nécessite à son tour que les services offrent une interface stable).
- L'avantage opérationnel que chaque microservice peut être mis à l'échelle indépendamment .
Si une mise à l'échelle indépendante n'est pas requise, les microservices sont beaucoup moins attrayants.
Un serveur de base de données est déjà une sorte de service que vous pouvez faire évoluer (quelque peu) indépendamment, par exemple en ajoutant des répliques en lecture. Vous mentionnez des procédures stockées. Les réduire pourrait avoir un effet si important que toute autre discussion sur l'évolutivité serait sans objet.
Et il est parfaitement possible d'avoir un monolithe évolutif qui inclut tous les services sous forme de bibliothèques. Vous pouvez ensuite évoluer en lançant plus d'instances du monolithe, ce qui nécessite bien sûr que chaque instance soit sans état.
Cela a tendance à bien fonctionner jusqu'à ce que le monolithe soit trop grand pour être déployé raisonnablement, ou si certains services ont des besoins en ressources spéciaux pour que vous souhaitiez les faire évoluer indépendamment. Les domaines problématiques qui impliquent des ressources supplémentaires peuvent ne pas impliquer un modèle de données distinct.
Avez-vous une solide analyse de rentabilisation?
Vous êtes conscient des besoins commerciaux de votre organisation et pouvez donc créer un argument pour une architecture de base de données par microservice, basée sur une analyse:
- qu'une certaine échelle est requise, et cette architecture est l'approche la plus rentable pour obtenir cette évolutivité, compte tenu de l'effort de développement accru pour une telle configuration et des solutions alternatives; et
- que vos exigences commerciales permettent d'assouplir les garanties ACID pertinentes, sans entraîner divers problèmes tels que ceux évoqués ci-dessus.
Inversement, si vous n'êtes pas en mesure de le démontrer, en particulier si la conception actuelle de la base de données est capable de prendre en charge une échelle suffisante dans le futur (comme vos collègues semblent le croire), alors vous avez également votre réponse.
L'évolutivité comporte également un important composant YAGNI. Face à l'incertitude, il s'agit d'une décision commerciale stratégique sur la construction de l'évolutivité maintenant (coûts totaux inférieurs, mais implique des coûts d'opportunité et peut ne pas être nécessaire) par rapport au report de certains travaux sur l'évolutivité (coûts totaux plus élevés si nécessaire, mais vous avez une meilleure idée de l'échelle réelle). Ce n'est pas avant tout une décision technique.