Tous les produits
Search
Centre de documentation

ApsaraMQ for Kafka:Why is a partition consumed by multiple consumer threads?

Dernière mise à jour :Aug 11, 2026

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 :

  1. Le consommateur C1 rejoint un groupe de consommateurs en tant que leader et reçoit l'assignation de la partition test-0.

  2. Le consommateur C2 rejoint le même groupe. C1 conserve test-0 ; C2 ne reçoit aucune partition.

  3. 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.

  4. C1 récupère et rejoint le groupe avec son ancienne assignation (test-0). Lors du rééquilibrage, C1 et C2 indiquent tous deux test-0 comme étant leur assignation actuelle.

  5. L'assigneur StickyAssignor ne vérifie pas la présence de doublons et assigne donc test-0 aux 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 :

  1. Ajoutez CooperativeStickyAssignor en 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");
  2. 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 pas StickyAssignor sur les versions de clients antérieures à 2,3. Même après l'application du correctif, CooperativeStickyAssignor reste généralement le meilleur choix, car il prend en charge le rééquilibrage incrémentiel sans mettre en pause tous les consommateurs.