Kafka — Consumer Rebalance
Contexte
Dans Kafka, les consumers d'un même consumer group se partagent les partitions d'un topic. Quand un consumer rejoint ou quitte le groupe, Kafka redistribue les partitions — c'est le rebalance.
Quand un rebalance se déclenche
- un consumer rejoint le groupe (scale up)
- un consumer quitte le groupe (crash, shutdown, scale down)
- un consumer ne répond plus (heartbeat timeout)
- le nombre de partitions change
- changement d'abonnement (subscribe à un nouveau topic)
Fonctionnement
sequenceDiagram
participant C1 as Consumer 1
participant C2 as Consumer 2
participant GC as Group Coordinator
C2->>GC: JoinGroup
GC->>C1: Rebalance triggered
GC->>C2: Rebalance triggered
Note over GC: Toutes les partitions sont révoquées
GC->>C1: Assign P0, P1
GC->>C2: Assign P2, P3
Pendant le rebalance :
- aucun consumer ne consomme — c'est un stop-the-world
- les partitions sont révoquées puis réassignées
- la durée dépend du nombre de consumers et de partitions
Stratégies d'assignation
RangeAssignor (défaut)
Assigne les partitions par plage continue à chaque consumer :
Consumer 1 → P0, P1, P2
Consumer 2 → P3, P4, P5
RoundRobinAssignor
Distribution circulaire :
Consumer 1 → P0, P2, P4
Consumer 2 → P1, P3, P5
StickyAssignor
Minimise les mouvements de partitions lors d'un rebalance :
Avant : C1 → P0,P1 C2 → P2,P3
C3 rejoint
Après : C1 → P0,P1 C2 → P2 C3 → P3
Préféré en production pour réduire l'impact des rebalances.
CooperativeStickyAssignor
Rebalance incrémental — seules les partitions qui changent de propriétaire sont révoquées :
partition.assignment.strategy=org.apache.kafka.clients.consumer.CooperativeStickyAssignor
- pas de stop-the-world complet
- les consumers continuent de consommer les partitions non affectées
Configuration clé
# Délai avant qu'un consumer soit considéré mort
session.timeout.ms=45000
# Intervalle des heartbeats
heartbeat.interval.ms=15000
# Temps max entre deux poll() avant exclusion
max.poll.interval.ms=300000
# Stratégie d'assignation
partition.assignment.strategy=org.apache.kafka.clients.consumer.CooperativeStickyAssignor
Warning
Si max.poll.interval.ms est dépassé (traitement trop long), le consumer est exclu du groupe et un rebalance est déclenché. Ajuster cette valeur selon la durée de traitement.
Impact en production
| Problème | Cause | Solution |
|---|---|---|
| Rebalances fréquents | Consumers instables, timeouts trop courts | Augmenter session.timeout.ms, utiliser CooperativeSticky |
| Pause de consommation | Rebalance stop-the-world | Passer à CooperativeStickyAssignor |
| Duplicate processing | Offsets non commités avant le rebalance | Committer les offsets régulièrement, consumer idempotent |
| Rebalance en boucle | Traitement trop long, poll timeout | Augmenter max.poll.interval.ms ou réduire max.poll.records |
Bonnes pratiques
- utiliser
CooperativeStickyAssignorpour minimiser les interruptions - committer les offsets après chaque batch traité
- monitorer les métriques de rebalance (
rebalance-latency-avg,rebalance-rate-per-hour) - dimensionner le nombre de partitions en fonction du nombre max de consumers
- rendre les consumers idempotents pour tolérer les doublons post-rebalance
À retenir
- le rebalance est le mécanisme de redistribution des partitions dans un consumer group
- c'est coûteux — il interrompt la consommation
- CooperativeStickyAssignor réduit considérablement l'impact
- les timeouts mal configurés sont la cause principale des rebalances intempestifs