1
votes

Utiliser une clé différente pour chaque message dans kafka

Nous avons une configuration producteur-consommateur kafka en Java (utilisant spring-kafka, mais ce n'est probablement pas pertinent ici). La clé utilisée est String et la valeur est POJO personnalisé. Le producteur-consommateur communique sur un seul thème test-topic ayant 16 partitions. Le consommateur a une simultanéité de 16 pour pouvoir lire à partir de chaque partition en parallèle.

D'après la documentation et d'autres références, je comprends que - L'utilisation des clés null distribuera les messages envoyés par l'éditeur dans les partitions de manière circulaire. Il est conseillé d'utiliser des clés non nulles si je suis intéressé par la distribution des messages vers des partitions spécifiques dérivées à l'aide de clés

J'ai les requêtes suivantes ici -

  1. Actuellement, le producteur envoie une clé unique par message. Comme il s'agit d'une String unique par message, dans presque tous les cas, elle générera également un hashcode unique. Comment les messages seront-ils distribués ici, est-ce que ce sera à tour de rôle comme des clés null ou une logique de hachage qui répète l'utilisation de partitions ou de tout autre mécanisme de contrôle?
  2. Y a-t-il des avantages ou des inconvénients à utiliser des clés avec la stratégie mentionnée ci-dessus par rapport aux clés null ?
  3. Je n'ai aucune obligation de maintenir l'ordre ou le regroupement des messages. Dans ce cas, est-il judicieux d'utiliser des clés null ou est-il toujours agréable d'avoir une clé non nulle unique ou non unique par message, si oui, pourquoi?
  4. Les consommateurs lisent les messages par lots. Le fait d'avoir ou non un lot de clé a-t-il un impact différent sur les lectures au singulier?

0 commentaires

3 Réponses :


0
votes

Le client contrôle la partition sur laquelle il publie les messages. Ceci peut être fait au hasard, en mettant en œuvre une sorte d'équilibrage de charge aléatoire, ou peut être fait par une fonction de partitionnement sémantique. Nous exposons le interface de partitionnement sémantique en permettant à l'utilisateur de spécifier un clé pour partitionner et l'utiliser pour hacher sur une partition (il y a également une option pour remplacer la fonction de partition si nécessaire).

La clé est utilisée pour diviser les messages en différentes partitions. Avec une clé nulle, ils finiront tous dans la partition 0 d'après mon expérience.

Les clés nulles ne sont pas un bon choix de conception et ne doivent pas être utilisées en production. Peut-être juste pour le prototypage rapide.

Stratégie de partitionnement persistant Le partitionneur persistant résout le problème de la répartition des enregistrements sans clés en lots plus petits en sélectionnant une seule partition pour envoyer tous les enregistrements sans clé

public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster,
                     int numPartitions) {
    if (keyBytes == null) {
        return stickyPartitionCache.partition(topic, cluster);
    }

7 commentaires

Avec une clé nulle, ils finiront tous dans la partition 0 d'après mon expérience - non, le producteur de Kafka utilisera une stratégie de round robin


il existe de nombreuses stratégies de partitionnement et vous pouvez même définir votre propre sémantique de partitionnement. Essayez-le et vous verrez.


d'accord que nous pourrions spécifier une stratégie de partitionnement personnalisée, mais je parle de l'implémentation du producteur par défaut DefaultPartitioner


github.com/apache/kafka/blob/trunk/clients/src/main/java/org‌ /…


@VasiliySarzhynskyi il y a un décalage entre les différentes versions. C'était l'ancien comportement, vous avez raison. Il semble que la version actuelle implémente le partitionnement collant pour de meilleures performances ...


en effet, DefaultPartitioner a été modifié. mais quand même, une partition ne sera sélectionnée de la même manière qu'à l'intérieur d'un seul lot, mais pour le lot suivant, la partition en sera une autre.


Yepp, c'est ce que je pensais, mais je l'ai essayé et tous les messages avec des clés nulles se terminaient dans la partition 0. Quoi qu'il en soit, les clés nulles ne donnent pas une bonne distribution, et de plus elles sont considérées comme une mauvaise pratique et très inefficace. Quant au courtier, un message n'est qu'un bytearray et si vous voulez y faire de la logique métier, vous devez désérialiser et repartitionner par de nouvelles clés ...



0
votes

Si vous spécifiez la clé, la partition par défaut sera sélectionnée en fonction du hachage de la clé modulo nombre de partitions ( hash (clé)% partitions_number ). En ayant des clés uniques, vous aurez une distribution uniforme des messages par partitions. Vous pouvez également remplacer le comportement de la partition en fournissant à votre partitionneur personnalisé la logique requise.

D'après votre description, vous n'avez pas besoin de la clé, dans ce cas, utilisez null , cela va légèrement: 1) économiser les ressources sur le cluster Kafka (ne pas stocker la clé non nécessaire), 2 ) diminuer la latence du réseau, 3) l'application ne générera pas de clé unique et ne calculera pas le hachage à partir de celle-ci (tous ces points sont mineurs et non significatifs en comparaison si vous avez des clés). Les clés doivent être utilisées si vous souhaitez classer les messages ayant la même clé (mais ce n'est pas votre cas, car vous avez des clés uniques), ou si vous avez une logique métier basée sur cette clé. Le traitement par lots fonctionnera correctement avec les clés null .


0 commentaires

2
votes

Le producteur Kafka envoie un message à une partition spécifique basée sur DefaultPartitioner, un partitionneur personnalisé ou transmet des informations de partition lors de l'envoi d'un message pour obtenir l'écriture sur une partition spécifique. La clé définie comme nulle ou non nulle est basée sur vos cas d'utilisation et vos exigences, mais l'objectif principal est de distribuer vos messages sur différentes partitions pour être consommés par plusieurs consommateurs du groupe de consommateurs.

La clé non nulle garantit qu'une clé similaire se garera sur la même partition, ce qui vous aidera à regrouper plusieurs clés similaires sur le même compartiment pour d'autres analystes en même temps.La clé nulle vous permettra de distribuer vos messages de manière égale.

La clé non nulle aide toujours à transmettre les méta-détails du message pour un traitement ultérieur. Je voudrais préférer passer la clé non nulle avec un partitionneur personnalisé pour contrôler le flux de messages. Mais cela dépend des exigences spécifiques et si vous voulez passer la clé null, c'est tout à fait correct.

Remarque: dans la prochaine version d'Apache Kafka (2.5), vous pourrez définir Partitionneur RoundRobin comme stratégie de partition (KIP-369) qui n'est pas nécessaire à la clé pour être nulle. https://cwiki.apache.org/confluence/pages/viewpage. action? pageId = 89070828

  1. Si vous n'êtes pas défini de partitionneur personnalisé, il utilisera le partitionneur par défaut

Avant Apache Kafka 2.4, il passera par cycle l'un après l'autre et enverra l'enregistrement à chacun. Dans ce cas, l'ancienne stratégie de partitionnement avant Apache Kafka 2.4 consisterait à parcourir les partitions du sujet et à envoyer un enregistrement à chacune. Mais comme vous comprenez que les messages sont envoyés par lots avec le paramètre de configuration linger.ms, cela peut avoir un impact sur les performances de petits lots, car chacun va vers des partitions spécifiques.Apache Kafka introduit un nouveau partitionneur Sticky en cas de clé nulle

Apache Kafka a introduit Sticky Partitioner (KIP-480) dans Apache Kafka 2.4 en cas de clé nulle dans le partitionneur par défaut comme mentionné ci-dessous

Stratégie de partitionnement permanent

Le partitionneur collant résout le problème de la répartition des enregistrements sans clés en lots plus petits en sélectionnant une seule partition pour envoyer tous les enregistrements sans clé. Une fois que le lot de cette partition est rempli ou terminé, le partitionneur collant choisit au hasard et «colle» à une nouvelle partition. De cette façon, sur une plus longue période, les enregistrements sont à peu près répartis uniformément entre toutes les partitions tout en bénéficiant de l'avantage supplémentaire de tailles de lots plus importantes.

 entrez la description de l'image ici

Cliquez ici pour plus de détails

  1. Si vous passez une clé non nulle et un partitionneur personnalisé non défini, il sera utilisé DefaultPartitioner pour identifier la partition pour publier les messages. DefaultPartitioner utilise MurmurHash, une fonction de hachage non cryptographique qui est généralement utilisée pour la recherche basée sur le hachage. Ce hachage est ensuite utilisé dans une opération modulo (% numPartitions) afin de s'assurer que la partition retournée est dans la plage [0, N] où N est le nombre de partitions du sujet.

    retourne Utils.toPositive (Utils.murmur2 (keyBytes))% numPartitions;

  2. Vous pouvez également définir un partitionneur personnalisé et implémenter une logique pour sélectionner la partition https://kafka.apache.org/ 10 / javadoc / org / apache / kafka / clients / producteur / Partitioner.html

  3. Passer la partition explicitement lors de la publication d'un message

    / ** * Crée un enregistrement à envoyer à un sujet et une partition spécifiés * / public ProducerRecord (sujet de chaîne, partition entière, clé K, valeur V) { this (sujet, partition, null, clé, valeur, null); }


0 commentaires