8
votes

Est-ce que l'approvisionnement d'événements à l'aide de Database CDC est considéré comme une bonne architecture?

Lorsque nous parlons de sourcing d'événements, nous avons une architecture à double écriture simple où nous pouvons écrire dans la base de données, puis écrire les événements dans une file d'attente comme Kafka. D'autres systèmes en aval peuvent lire ces événements et agir sur / les utiliser en conséquence.

Mais le problème survient lorsque l'on essaie de synchroniser à la fois la base de données et les événements, car l'ordre de ces événements est nécessaire pour en tirer un sens.

Pour résoudre ce problème, les gens encouragent l'utilisation des journaux de validation de base de données comme source d'événements, et il existe des outils construits autour de celui-ci comme Spinal Tap d'Airbnb, Debezium de Redhat, Golden Gate d'Oracle, etc ... Cela résout le problème de cohérence, commande garantie et tout cela.

Mais le problème avec l'utilisation du journal de validation de la base de données comme source d'événements est que nous sommes étroitement couplés avec le schéma de base de données. Le schéma de base de données pour un micro-service est exposé et toutes les modifications importantes apportées au schéma de base de données, telles que le changement de type de données ou le changement de nom de colonne, peuvent en fait interrompre les systèmes en aval.

Est-ce que l'utilisation du DB CDC comme source d'événements est une bonne idée?

Présentation de ce problème et utilisation de Debezium pour la recherche d'événements


2 commentaires

Nous pouvons plutôt découpler les systèmes source (disons DB) et cible (en aval) de l'implémentation réelle. Les adaptateurs pourraient être utiles. En particulier pour le paysage Kafka, nous pourrions choisir d'utiliser Avro pour gérer la compatibilité de version de différents schémas de message.


Notez qu'en général, les questions sur l'architecture sont plus d'actualité chez Génie logiciel qu'ici; Stack Overflow est plus axé sur des problèmes tactiques spécifiques et étroits.


3 Réponses :


2
votes

Si vous utilisez la recherche d'événements:

Alors le couplage ne devrait pas exister. Le magasin d'événements est générique, il ne se soucie pas de l'état interne de vos Agrégats . Vous êtes dans le pire des cas couplé à la structure interne du magasin d'événements lui-même mais ce n'est pas spécifique à un microservice particulier.

Si vous n'utilisez pas le sourcing d'événements:

Dans ce cas, il existe un couplage entre la structure interne des agrégats et le composant CDC (qui capture la modification des données et publie l'événement dans une file d'attente de messages ou similaire). Afin de limiter les effets de ce couplage au microservice lui-même, le composant CDC devrait en faire partie. De cette manière, lorsque la structure interne des agrégats dans le microservice change, le composant CDC est également modifié et le monde extérieur ne le remarque pas. Les deux changements sont déployés en même temps.


4 commentaires

Lorsque vous dites "CDC devrait en faire partie", cela signifie-t-il que le microservice lui-même consommera le CDC et le convertira en événement et le publiera.


Le CDC a également deux cas d'utilisation, 1. Création d'événements pour d'autres services, 2. Partage de données avec le pipeline de données.


@RBanerjee Je veux dire le composant CDC, le processus ou tout ce qui suit le journal de validation et crée les événements à partir de celui-ci


@RBanerjee Le composant CDC peut par exemple être un side-car (processus ou conteneur d'événements) qui s'exécute le long du processus Microservice



2
votes

Extension de la réponse de Constantin:

<↓TLDR;

Le suivi / l'extraction du journal des transactions doit être caché aux autres.

Ce n'est pas strictement un flux d'événements, car vous ne devez pas y accéder directement à partir d'autres services. Il est généralement utilisé lors de la transition progressive d'un système hérité vers un système basé sur des microservices. Le flux pourrait ressembler à ceci:

  1. Le service A valide une transaction dans la base de données
  2. Un framework ou un service interroge le journal des commit et mappe les nouveaux commits à Kafka en tant qu'événements
  3. Le service B est abonné à un flux Kafka et consomme des événements à partir de là, et non de la base de données

Histoire plus longue:

Le service B ne voit pas que votre événement provient de la base de données et n'accède pas directement à la base de données. Les données de validation doivent être projetées dans un événement. Si vous modifiez la base de données, vous ne devez modifier votre règle de projection que pour mapper les validations du nouveau schéma au format d'événement «ancien», de sorte que les consommateurs ne doivent pas être modifiés. (Je ne connais pas Debezium, ni s'il peut faire cette projection).

Vos événements doivent être idempotents comme la publication d'un événement et la validation d'une transaction atomiquement est un problème dans un scénario distribué, et les outils garantiront au moins une livraison avec une sémantique de traitement exactement une fois au mieux, et la partie exactement une fois est plus rare. Cela est dû à une origine d'événement (le journal des transactions) n'est pas la même que le flux auquel accéderont d'autres services, c'est-à-dire qu'il est distribué. Et c'est toujours la partie producteur, le même problème existe avec Kafka-> canal grand public, mais pour une raison différente. De plus, Kafka ne se comportera pas comme un magasin d'événements , vous avez donc créé une file d'attente de messages.

Je recommande d'utiliser à la place un magasin d'événements dédié si possible, comme celui de Greg Young: https://eventstore.org/. Cela résout le problème en intégrant un magasin d'événements et un courtier de messages dans une solution unique. En stockant un événement (en JSON) dans un flux, vous le «publiez» également, car les consommateurs sont abonnés à ce flux. Si vous souhaitez découpler davantage les services, vous pouvez écrire des projections qui mappent les événements d'un flux à un autre flux. Votre consommation d'événements devrait également être idempotente avec cela, mais vous obtenez un magasin d'événements qui est partitionné par des agrégats et est assez rapide à lire.

Si vous souhaitez également stocker les données dans la base de données SQL, écoutez ces événements et insérez / mettez à jour les tables basées sur eux, n'utilisez simplement pas votre base de données SQL comme magasin d'événements car il sera difficile de l'implémenter à droite (à l'épreuve des pannes).

Pour la partie commande: la lecture des événements d'un flux sera ordonnée. Les projections qui regroupent plusieurs flux d'événements ne peuvent garantir que l'ordre entre les événements provenant du même flux. C'est généralement plus que suffisant. (btw vous pouvez réorganiser les messages en fonction d'un champ du côté consommateur si nécessaire.)


4 commentaires

Le flux que vous avez mentionné: "Un framework ou un service interroge le journal des commit et mappe les nouveaux commits à Kafka en tant qu'événements" => Comment gardez-vous le code / déploiement du service A et ce framework / service qui interroge le journal des commit en synchronisation? Comme un changement radical dans le schéma de base de données par le service A peut casser ce cadre / service.


Debezium / d'autres outils d'analyse TxLog fourniront des événements idempotents. Les événements ne seront publiés qu'une fois la validation de la base de données effectuée. Par exemple, si le salaire d'un employé a augmenté, il donnera la table Employé: Ancien {Salaire: 100}, Nouveau {Salaire: 150}.


Si le CDC est un framework et qu'il s'exécute dans le service A, vous pouvez simplement réécrire la règle de projection et la valider avec le changement de schéma de base de données. Par exemple. vous avez renommé salaire en paiement , puis modifiez la projection pour mapper paiement sur salaire , car les consommateurs ne devraient pas vous connaître renommé un champ. Si vous ne pouvez pas écrire une projection qui cache la modification, vous devez également modifier les clients. Vous pouvez également utiliser des événements versionnés, et si les modifications de schéma sont incompatibles, un nouveau type d'événement ou une nouvelle version est publié.


S'il s'agit d'un service, cela dépend de la façon dont vous déployez. Par exemple. vous pouvez arrêter le CDC, déployer le nouveau service A avec un nouveau schéma, puis modifier la projection pour le CDC et le redéployer également. Il rattrapera éventuellement si de nouvelles transactions sont déjà validées dans le service A avant le démarrage du CDC. La partie la plus importante est de convertir les événements publiés à partir du CDC en un format d'événement unifié, peut-être que vous pouvez même le faire dans Kafka au lieu du CDC.



1
votes

Est-ce que l'utilisation du DB CDC comme source d'événements est une bonne idée?

"Est-ce une bonne idée?" est une question qui dépendra de votre contexte, des coûts et des avantages des différents compromis que vous devez faire.

Cela dit, ce n'est pas une idée cohérente avec l'héritage du sourcing événementiel tel que je l'ai appris.

Le sourcing d'événements - l'idée que notre livre d'archives est un registre des changements d'état - existe depuis longtemps. Après tout, lorsque nous parlons de "grand livre", nous faisons en fait allusion à ces documents écrits il y a des siècles qui suivaient le commerce.

Mais une grande partie de la discussion sur l'approvisionnement d'événements dans les logiciels est fortement influencée par la conception axée sur le domaine; DDD préconise (entre autres) d'aligner vos concepts de code avec les concepts du domaine que vous modélisez.

Voici donc le problème: sauf si vous êtes dans un cas extrême, votre base de données est probablement une application à usage général que vous personnalisez / configurez pour répondre à vos besoins. La capture des données de changement va être limitée par le fait qu'elle est mise en œuvre à l'aide de mécanismes à usage général. Ainsi, les événements produits vont ressembler à des documents de patch à usage général (voici la différence entre avant et après).

Mais si nous essayons d'aligner nos événements avec nos concepts de domaine (c'est-à-dire, que signifie ce changement de notre état persistant ), alors les documents de correctifs sont un pas dans la mauvaise direction.

Par exemple, le domaine out peut avoir plusieurs "événements" qui modifient les mêmes ensembles de champs, ou très similaires, dans notre modèle. Essayer de redécouvrir la motivation d'un changement par rétro-ingénierie du diff est une sorte de problème stupide à avoir; surtout lorsque nous avons déjà combattu avec le même type de problème d'apprentissage conception d'interface utilisateur .

Dans certains domaines, un changement à usage général suffit. Dans certains contextes, un changement à but général est suffisant pour le moment. Chevaux pour les cours.

Mais ce n'est pas vraiment le genre d'implémentation dont parle la communauté "Event Sourcing".


0 commentaires