Je reviens toujours à ce QA. Et je n'ai pas trouvé les réponses existantes suffisamment nuancées, alors j'ajoute celle-ci.
TL; DR. Oui ou non, en fonction de l'utilisation de votre source d'événements.
Il y a deux types principaux de systèmes issus d'événements dont je suis au courant.
Processeurs d'événements en aval = Oui
Dans ce type de système, les événements se produisent dans le monde réel et sont enregistrés comme des faits. Comme un système d'entrepôt pour garder une trace des palettes de produits. Il n'y a fondamentalement aucun événement conflictuel. Tout s'est déjà passé, même si c'était faux. (C'est-à-dire que la palette 123456 a été placée sur le camion A, mais était prévue pour le camion B.) Ensuite, les faits sont vérifiés pour les exceptions via des mécanismes de rapport. Kafka semble bien adapté à ce type d'application de traitement d'événements en aval.
Dans ce contexte, il est compréhensible que les gens de Kafka le préconisent en tant que solution de sourçage d'événements. Parce qu'il est assez similaire à la façon dont il est déjà utilisé, par exemple, dans les flux de clics. Cependant, les personnes qui utilisent le terme Event Sourcing (par opposition au Stream Stream) font probablement référence à la deuxième utilisation ...
Source de vérité contrôlée par l'application = Non
Ce type d'application déclare ses propres événements à la suite de demandes d'utilisateurs passant par la logique métier. Kafka ne fonctionne pas bien dans ce cas pour deux raisons principales.
Manque d'isolement d'entité
Ce scénario doit pouvoir charger le flux d'événements pour une entité spécifique. La raison courante en est de créer un modèle d'écriture transitoire pour la logique métier à utiliser pour traiter la demande. Cela n'est pas pratique à Kafka. L'utilisation d'un sujet par entité pourrait permettre cela, sauf qu'il ne s'agit pas d'un démarreur lorsqu'il peut y avoir des milliers ou des millions d'entités. Cela est dû aux limites techniques de Kafka / Zookeeper.
L'une des principales raisons d'utiliser un modèle d'écriture transitoire de cette manière est de rendre les changements de logique métier bon marché et faciles à déployer.
L'utilisation de rubrique par type est recommandée à la place pour Kafka, mais cela nécessiterait de charger des événements pour chaque entité de ce type juste pour obtenir des événements pour une seule entité. Puisque vous ne pouvez pas dire par position de journal quels événements appartiennent à quelle entité. Même en utilisant des instantanés pour démarrer à partir d'une position de journal connue, cela peut représenter un nombre important d'événements à effectuer.
Absence de détection des conflits
Deuxièmement, les utilisateurs peuvent créer des conditions de concurrence critique en raison de demandes simultanées contre la même entité. Il peut être tout à fait indésirable de sauvegarder des événements conflictuels et de les résoudre après coup. Il est donc important de pouvoir prévenir les événements conflictuels. Pour mettre à l'échelle la charge des demandes, il est courant d'utiliser des services sans état tout en évitant les conflits d'écriture à l'aide d'écritures conditionnelles (écriture uniquement si le dernier événement d'entité était #x). Aka Optimistic Concurrency. Kafka ne prend pas en charge la concurrence optimiste. Même s'il la soutenait au niveau du sujet, il faudrait que ce soit jusqu'au niveau de l'entité pour être efficace. Pour utiliser Kafka et éviter les événements conflictuels, vous devez utiliser un rédacteur sérialisé avec état au niveau de l'application. Il s'agit d'une exigence / restriction architecturale importante.
Plus d'informations
Mise à jour par commentaire
Le commentaire a été supprimé, mais la question était quelque chose comme: qu'utilisent les gens pour le stockage des événements alors?
Il semble que la plupart des gens déploient leur propre implémentation de stockage d'événements sur une base de données existante. Pour les scénarios non distribués, comme les back-ends internes ou les produits autonomes, il est bien documenté comment créer un magasin d'événements basé sur SQL. Et il y a des bibliothèques disponibles sur des bases de données de différents types. Il existe également EventStore , qui est conçu à cet effet.
Dans les scénarios distribués, j'ai vu quelques implémentations différentes. Le projet Panther de Jet utilise Azure CosmosDB , avec la fonctionnalité Change Feed pour informer les auditeurs. Une autre implémentation similaire dont j'ai entendu parler sur AWS utilise DynamoDB avec sa fonction Streams pour informer les auditeurs. La clé de partition devrait probablement être l'ID de flux pour la meilleure distribution de données (pour réduire la quantité de surprovisionnement). Cependant, une relecture complète à travers les flux dans Dynamo coûte cher (lecture et coût). Cet implément a donc également été configuré pour Dynamo Streams pour vider les événements vers S3. Lorsqu'un nouvel auditeur arrive en ligne, ou qu'un auditeur existant veut une relecture complète, il lit S3 pour rattraper son retard en premier.
Mon projet actuel est un scénario multi-locataire, et j'ai roulé le mien sur Postgres. Quelque chose comme Citus semble approprié pour l'évolutivité, le partitionnement par stream + tentant.
Kafka est toujours très utile dans les scénarios distribués. C'est un problème non trivial d'exposer les événements de chaque service à d'autres services. Un magasin d'événements n'est généralement pas construit pour cela, mais c'est précisément ce que Kafka fait bien. Chaque service a sa propre source de vérité interne (peut être le stockage d'événements ou autre), mais écoute Kafka pour savoir ce qui se passe "à l'extérieur". Le service peut également publier des événements à Kafka pour informer "l'extérieur" des choses intéressantes que le service a faites.