Symptômes
Lorsqu'un client consommateur utilise la stratégie d'assignation des partitions StickyAssignor, plusieurs threads de consommateurs traitent la même partition. Cette situation entraîne un traitement dupliqué ou désordonné des messages.
Cause
Il s'agit d'un bogue connu (KAFKA-7026 / KIP-341) présent dans les versions du client Apache Kafka antérieures à la 2,3. L'assigneur StickyAssignor ne supprime pas les doublons d'assignations de partitions lorsqu'un consommateur rejoint un groupe avec des données d'assignation obsolètes.
Le scénario suivant reproduit le problème :
Le consommateur C1 rejoint un groupe de consommateurs en tant que leader et reçoit l'assignation de la partition
test-0.Le consommateur C2 rejoint le même groupe. C1 conserve
test-0; C2 ne reçoit aucune partition.C1 devient indisponible (par exemple, en raison d'une longue pause GC). C2 devient le nouveau leader et prend le contrôle de
test-0.C1 récupère et rejoint le groupe avec son ancienne assignation (
test-0). Lors du rééquilibrage, C1 et C2 indiquent tous deuxtest-0comme étant leur assignation actuelle.L'assigneur
StickyAssignorne vérifie pas la présence de doublons et assigne donctest-0aux deux consommateurs.
Solution
Option 1 : Mettre à niveau le client Kafka vers la version 2,3 ou ultérieure (recommandé)
Ce bogue a été corrigé dans Apache Kafka 2,3. Mettez à jour la dépendance du client Kafka dans votre application :
<!-- Maven example -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.3.0</version> <!-- or later -->
</dependency>
Option 2 : Basculer vers une autre stratégie d'assignation des partitions
Si vous ne pouvez pas effectuer la mise à niveau immédiatement, optez pour une autre stratégie d'assignation des partitions. Le tableau suivant décrit les stratégies disponibles :
| Stratégie | Nom de classe | Description | Compromis |
|---|---|---|---|
| Range (par défaut) | RangeAssignor |
Répartit équitablement les partitions de chaque topic entre les consommateurs. | Simple et prévisible. Peut entraîner une répartition inégale lorsque le nombre de partitions n'est pas un multiple du nombre de consommateurs. |
| Round-robin | RoundRobinAssignor |
Assigne les partitions une par one selon un cycle round-robin à tous les consommateurs. | Plus équilibrée que Range. Peut provoquer davantage de déplacements de partitions lors des rééquilibrages. |
| Cooperative sticky | CooperativeStickyAssignor |
Utilise la même logique d'équilibrage que StickyAssignor, mais s'appuie sur le protocole de rééquilibrage coopératif pour éviter les interruptions totales (« stop-the-world »). |
Minimise les déplacements de partitions et évite le bogue d'assignation en double. Nécessite une migration en deux étapes depuis les assignateurs utilisant le protocole eager. |
Pour modifier la stratégie, définissez la propriété de configuration du consommateur partition.assignment.strategy :
props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,
"org.apache.kafka.clients.consumer.RoundRobinAssignor");
Migrer vers CooperativeStickyAssignor
Pour migrer de StickyAssignor vers CooperativeStickyAssignor au sein d'un groupe de consommateurs actif sans interruption de service, effectuez un redémarrage progressif en deux étapes :
-
Ajoutez
CooperativeStickyAssignoren tant que stratégie secondaire parallèlement à la stratégie actuelle, puis redémarrez progressivement tous les consommateurs.props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG, "org.apache.kafka.clients.consumer.StickyAssignor," + "org.apache.kafka.clients.consumer.CooperativeStickyAssignor"); -
Une fois que tous les consommateurs ont pris en compte la nouvelle configuration, basculez exclusivement vers
CooperativeStickyAssignor, puis effectuez un second redémarrage progressif.props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG, "org.apache.kafka.clients.consumer.CooperativeStickyAssignor");
N'utilisez pasStickyAssignorsur les versions de clients antérieures à 2,3. Même après l'application du correctif,CooperativeStickyAssignorreste généralement le meilleur choix, car il prend en charge le rééquilibrage incrémentiel sans mettre en pause tous les consommateurs.