20 - Anti-patterns à éviter avec Kafka
Certains usages de Kafka et de l’event-driven semblent pratiques au début, mais se transforment rapidement en points de douleur. Un anti-pattern est une solution qui paraît efficace à court terme, mais qui crée des coûts massifs à moyen ou long terme. Dans une banque, ces coûts se traduisent par des incidents opérationnels, des incohérences comptables et des risques réglementaires.
Cet article recense les anti-patterns les plus courants et propose des alternatives robustes.
Anti-pattern 1: Kafka comme RPC
Symptôme: publier un event et attendre une réponse immédiate. Pourquoi c’est mauvais: Kafka n’est pas un bus request/response. Cette approche crée une latence imprévisible et un couplage fort. Les consumers n’ont pas la même disponibilité qu’une API synchrone, et la gestion des timeouts est complexe.
Exemple bancaire: demander une autorisation de virement via Kafka et attendre la réponse bloque le client si un consumer est en retard. Le SLA devient incontrôlable.
Alternative: utiliser un appel synchrone explicite (HTTP/RPC) pour la commande, puis publier un event une fois la décision prise.
Anti-pattern 2: Kafka comme base de données
Symptôme: stocker des états complets et interroger Kafka comme un store. Pourquoi c’est mauvais: Kafka est un log, pas un moteur de requêtes. Lire un topic pour reconstituer l’état en temps réel est coûteux et fragile.
Exemple bancaire: chercher un solde en lisant un topic transactionnel complet rend les réponses lentes et non fiables.
Alternative: construire des projections (read models) adaptées, ou utiliser une base de lecture dédiée.
Anti-pattern 3: Topic unique pour tout
Symptôme: un seul topic global pour tous les events. Pourquoi c’est mauvais: gouvernance impossible, ACLs inefficaces, coûts élevés de consommation. Les équipes ne peuvent pas isoler leurs flux.
Exemple bancaire: tous les événements dans prod.events empêchent de
limiter l’accès aux flux sensibles (paiements, PII).
Alternative: découper par domaine et intention, avec naming explicite.
Anti-pattern 4: Commands et events mélangés
Symptôme: même topic pour commands et events. Pourquoi c’est mauvais: ambiguïté, erreurs d’interprétation, confusion sur le sens métier. Les consumers ne savent pas si un message est une intention ou un fait.
Exemple bancaire: un consumer fraude traite une command InitiateTransfer
comme un fait, déclenchant un scoring prématuré.
Alternative: séparer les topics par intention (cmd vs evt).
Anti-pattern 5: Payloads génériques
Symptôme: payloads “data” ou “payload” sans structure. Pourquoi c’est mauvais: impossible à versionner correctement, difficile à comprendre et à maintenir. Les consumers dépendent de conventions implicites.
Exemple bancaire: un champ data contient tantôt un virement, tantôt un
bénéficiaire, créant un chaos d’intégration.
Alternative: schémas explicites et versionnés, avec contrats clairs.
Anti-pattern 6: DLQ comme flux normal
Symptôme: utiliser la DLQ comme pipeline standard. Pourquoi c’est mauvais: masque les erreurs structurelles et normalise les échecs. La DLQ devient un “second flux” non gouverné.
Exemple bancaire: un flux de virements finit par passer majoritairement en DLQ, rendant l’observabilité trompeuse.
Alternative: corriger la cause racine, puis rejouer proprement les events.
Anti-pattern 7: Event sourcing partout
Symptôme: appliquer l’event sourcing à tous les services. Pourquoi c’est mauvais: complexité excessive, coûts d’exploitation élevés. Tous les domaines n’ont pas besoin d’un historique complet.
Exemple bancaire: event sourcing appliqué à des flux de notifications, créant une complexité inutile sans bénéfice métier.
Alternative: réserver l’event sourcing aux domaines où l’historique est essentiel (ledger, audit réglementaire).
Anti-pattern 8: Asynchronisme total
Symptôme: tout rendre asynchrone, même la décision critique. Pourquoi c’est mauvais: UX incohérente, responsabilité floue. Le client ne sait pas si la banque s’est engagée.
Exemple bancaire: API répond “virement en cours” sans décision claire, créant de la confusion et des appels au support.
Alternative: synchronisme pour la décision, asynchrone pour la diffusion.
Anti-pattern 9: Replays sans isolation
Symptôme: rejouer un flux en production sans contrôle. Pourquoi c’est mauvais: doublons, notifications réémises, effets externes répétés. Cela crée des incidents secondaires.
Exemple bancaire: replay d’un flux de paiements déclenche des notifications aux clients déjà débités.
Alternative: mode dry-run, gateways désactivables, replays isolés.
Anti-pattern 10: Absence d’observabilité
Symptôme: pas de métriques, pas de tracing. Pourquoi c’est mauvais: incidents invisibles, diagnostics lents.
Exemple bancaire: impossible de reconstituer le parcours d’un virement litigieux lors d’un audit.
Alternative: dashboards, correlation_id, alerting structuré.
Anti-pattern 11: Compaction mal utilisée
Symptôme: compacter un flux transactionnel. Pourquoi c’est mauvais: destruction d’audit, impossibilité de replay historique complet.
Exemple bancaire: un topic de transactions compacté ne permet plus de prouver l’historique en cas de litige.
Alternative: compaction pour les référentiels, retention pour les flux.
Anti-pattern 12: CDC sur tables métier sensibles
Symptôme: CDC expose des données PII sans filtrage. Pourquoi c’est mauvais: risque réglementaire majeur, fuite de données.
Exemple bancaire: CDC sur la table clients expose des IBAN complets dans Kafka, accessible à trop d’équipes.
Alternative: CDC sur outbox dédiée avec filtrage et tokenisation.
Anti-pattern 13: Couplage fort aux consumers
Symptôme: le producer change un champ en fonction d’un consumer spécifique. Pourquoi c’est mauvais: les producers deviennent dépendants d’un downstream, ce qui casse l’indépendance des services. Les évolutions deviennent lentes.
Exemple bancaire: un service Paiements ajoute un champ spécial uniquement pour un consumer Reporting, puis doit maintenir ce champ indéfiniment.
Alternative: gouverner le contrat public et publier des events stables, en laissant chaque consumer adapter sa projection.
Anti-pattern 14: Effets externes non déterministes
Symptôme: appels externes en plein traitement d’event sans journalisation. Pourquoi c’est mauvais: le replay devient impossible, les résultats varient.
Exemple bancaire: un scoring AML dépend d’un service externe dont les réponses changent dans le temps; un replay produit un résultat différent.
Alternative: journaliser les requêtes externes ou transformer les appels en events distincts, afin de rendre le traitement déterministe.
Anti-pattern 15: “Exactly-once” comme garantie universelle
Symptôme: supposer que l’exactly-once résout tous les doublons. Pourquoi c’est mauvais: la garantie est limitée au pipeline Kafka et ne couvre pas les effets externes. Elle peut créer un faux sentiment de sécurité.
Exemple bancaire: un consumer publie dans Kafka en exactly-once, mais fait un débit externe non idempotent. Le doublon reste possible.
Alternative: idempotence métier + déduplication, en complément des mécanismes Kafka.
Anti-pattern 16: Ignorer le backpressure
Symptôme: consumers saturés, lag croissant, rebalances fréquents. Pourquoi c’est mauvais: le système devient instable et les SLA explosent.
Exemple bancaire: un flux de fraude en streaming se bloque et ralentit les virements instantanés.
Alternative: backpressure explicite, scaling du consumer group, seuils préventifs et mode dégradé pour les flux secondaires.
Anti-pattern 17: Exposition excessive des PII
Symptôme: events publics contenant des données sensibles complètes. Pourquoi c’est mauvais: risques RGPD et accès non contrôlé.
Exemple bancaire: un event AccountOpened contient l’IBAN complet et le
numéro de document d’identité.
Alternative: pseudonymisation, tokenisation, séparation des topics par sensibilité et filtrage systématique.
Anti-pattern 18: Absence de classification des données
Symptôme: mêmes politiques de rétention pour tous les topics. Pourquoi c’est mauvais: coûts excessifs et risques réglementaires.
Exemple bancaire: conserver indéfiniment des events contenant des PII.
Alternative: classification explicite (public, interne, restreint) et politiques de rétention adaptées.
Cas d’étude: migration ratée vers l’event-driven
Une banque migre un système de paiement vers Kafka. Par manque de gouvernance, les équipes mélangent commands et events, et publient des payloads génériques. Le reporting aval casse après un changement de champ, et le replay déclenche
des notifications multiples. La correction a pris des semaines, car aucune observabilité n’était en place. Ce scénario illustre que les anti-patterns se combinent et amplifient leurs effets.
Leçons tirées: l’absence de contrats explicites et de tests de compatibilité augmente le coût d’incident. Dans une banque, ces incidents touchent la confiance client et déclenchent des audits. La remédiation doit donc être structurée: stabiliser d’abord les flux critiques, puis étendre la gouvernance aux flux secondaires. Sans cette discipline, chaque nouveau service ajoute un risque supplémentaire au système.
Anti-patterns de gouvernance
La gouvernance est souvent négligée. Sans ownership clair, les topics deviennent des zones grises: personne n’ose les modifier, mais tout le monde dépend d’eux. Dans une banque, cela bloque l’évolution des produits et crée une dette organisationnelle. Un anti-pattern fréquent est l’absence de catalogue d’events: sans inventaire, on ne sait plus qui consomme quoi.
Autre dérive: changer un schéma sans coordination avec les équipes aval. Cela peut casser un reporting réglementaire sans signal immédiat. La gouvernance
doit inclure des revues de schéma, des SLA et des politiques de rétention
documentées. Sans cela, l’event-driven devient un “dark data lake”.
Remédiation progressive
Corriger les anti-patterns doit être progressif pour éviter un “big bang”. Une stratégie efficace: - stabiliser d’abord les contrats publics (schémas, naming), - sécuriser l’exécution (idempotence, outbox), - renforcer l’observabilité (tracing, dashboards, alerting).
En banque, cette remédiation doit être alignée avec les fenêtres de changement validées et les exigences de conformité. L’objectif est de réduire le risque sans interrompre les services critiques.
Impact économique et réglementaire
Les anti-patterns ne coûtent pas seulement du temps d’ingénierie. Ils augmentent les coûts d’infrastructure (topics inutiles, replays fréquents), créent des incidents clients et génèrent des risques d’audit. Dans une banque, un incident de reporting peut entraîner des pénalités ou des contrôles renforcés.
Mesurer ces impacts aide à justifier les investissements de remédiation. Un catalogue d’events bien gouverné et une observabilité complète coûtent moins que plusieurs incidents majeurs sur un flux critique.
Priorisation des anti-patterns
Tous les anti-patterns n’ont pas la même gravité. Une mauvaise séparation commands/events ou une absence d’idempotence doit être corrigée en priorité car elle touche directement la cohérence comptable. Les problèmes de naming ou de documentation viennent ensuite, car leur impact est plus diffus.
Cette priorisation doit être alignée avec les domaines métier: le ledger et les flux de paiement passent avant les notifications ou l’analytics. C’est cette stratégie qui permet de progresser sans paralyser l’organisation.
Checklist anti-patterns
- Les commands et events sont-ils séparés ?
- Les schémas sont-ils versionnés et validés en CI ?
- Les consumers sont-ils idempotents ?
- Les effets externes sont-ils isolés pour les replays ?
- Les topics sensibles sont-ils protégés ?
Bonnes pratiques de base
- Séparer commands et events.
prod.corebanking.transfer.cmd.initiate.v1prod.corebanking.transfer.evt.initiated.v1
- Gouverner les schémas et versionner les contracts.
- Garder un flux clair et documenté.
Conclusion
Les anti-patterns event-driven sont séduisants car ils simplifient à court terme. En banque, ils génèrent des coûts massifs à long terme. La discipline sur les schémas, la séparation des intentions, et l’observabilité sont les principaux antidotes. Investir dans ces pratiques réduit le risque opérationnel et accélère l’innovation. Les équipes peuvent alors ajouter de nouveaux services sans répéter les mêmes erreurs ni compromettre la stabilité des flux critiques. Cette rigueur est particulièrement cruciale pour les flux de paiement et de ledger. C’est aussi un message clair pour la conformité: les risques sont connus, documentés et maîtrisés. Elle crée une base solide pour la croissance technique et métier durable réelle.