Que fait Construction de consommateurs Kafka ?
Quand l'utiliser
- Écrire ou déboguer des consommateurs/producteurs Kafka.
- Choisir la stratégie de validation des offsets et les garanties de livraison.
- Ajuster le parallélisme des groupes de consommateurs, le rééquilibrage ou la gestion des messages morts.
- Ne PAS utiliser pour le traitement de flux / fenêtrage (utiliser
processing-streaming-data).
Workflow
- [ ] Dimensionner les partitions en fonction du parallélisme cible (consommateurs <= partitions)
- [ ] Valider les offsets APRÈS le traitement réussi
- [ ] Rendre le sink idempotent (upsert par clé d'événement)
- [ ] Gérer les rééquilibrages (valider lors de la révocation, éviter les longs intervalles de poll)
- [ ] Router les messages empoisonnés vers un sujet de lettres mortes
- Les partitions limitent le parallélisme. Un groupe de consommateurs ne peut monter en charge que jusqu'au nombre de partitions ; les consommateurs supplémentaires restent inactifs. Choisissez les partitions en fonction du débit de pointe.
- Valider après le traitement. Ne validez les offsets qu'une fois le travail durablement effectué, pas avant — une validation précoce entraîne la perte de messages en cas de crash.
- Sink idempotent. Au-moins-une-fois signifie des doublons en cas de nouvelle tentative ; effectuez un upsert avec une clé d'événement stable pour que le retraitement soit inoffensif.
- Les rééquilibrages arrivent. Validez lors de la révocation de partition et maintenez les intervalles
poll()en dessous demax.poll.interval.mspour que le broker n'expulse pas le consommateur. - Les messages empoisonnés sont envoyés vers un sujet de lettres mortes avec l'erreur, afin qu'un mauvais enregistrement ne bloque pas toute la partition.
Patterns
Commit manuel après traitement :
consumer = KafkaConsumer("orders", group_id="etl",
enable_auto_commit=False,
max_poll_records=500)
for msg in consumer:
try:
upsert(process(msg)) # idempotent par clé
consumer.commit() # valider seulement après succès
except PoisonError:
send_to_dlq(msg)
consumer.commit() # ignorer le mauvais enregistrement
Producteur idempotent / transactionnel — définissez enable.idempotence=true (dédouble les tentatives) et utilisez des transactions pour un read-process-write exactement-une-fois entre sujets.
Réglage du débit — augmentez max.poll.records, fetch.min.bytes, et traitez par lots ; gardez le traitement rapide pour éviter l'expulsion lors du rééquilibrage.
Pièges courants
- Auto-commit + traitement lent — les offsets avancent avant la fin du travail ; un crash entraîne la perte de messages. Préférez le commit manuel après traitement.
- Plus de consommateurs que de partitions — les consommateurs supplémentaires restent inactifs ; repartitionnez pour monter en charge.
- Traitement long entre les polls — dépasse
max.poll.interval.mset déclenche des rééquilibrages infinis ; traitez par lots limités ou utilisez un worker en arrière-plan. - Absence de chemin de lettres mortes — un message empoisonné bloque toute la partition.
- Compter sur l'exactement-une-fois sans sink idempotent — tout saut au-moins-une-fois réintroduit des doublons.