Aller au contenu

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 CooperativeStickyAssignor pour 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

Voir aussi