KafkaProducer 循环分配不适用于同一密钥

Kle*_*ios 0 apache-kafka kafka-producer-api

我试图了解卡夫卡是如何工作的。我读到,默认情况下,Kafka 会在分区之间以循环方式分发来自生产者的消息。

但是,如果消息具有相同的密钥,为什么这些消息总是放在同一个分区中?(未配置分区键策略)。

例如,使用下面的代码,消息始终放置在同一分区中:

KafkaProducer<String, String> producer = new KafkaProducer<>(properties);
String key = properties.getProperty("dev.id");
producer.send(new ProducerRecord<String, String>(properties.getProperty("kafka.topic"), key, value), new EventGeneratorCallback(key));
Run Code Online (Sandbox Code Playgroud)

使用不同的密钥,消息以循环方式分发:

KafkaProducer<String, String> producer = new KafkaProducer<>(properties);
String key = properties.getProperty("dev.id") + UUID.randomUUID().toString();
producer.send(new ProducerRecord<String, String>(properties.getProperty("kafka.topic"), key, value), new EventGeneratorCallback(key));
Run Code Online (Sandbox Code Playgroud)

ppa*_*rno 5

这正是 Kafka 生产者的工作方式。此行为由您可以在官方存储库中找到DefaultPartitioner的类定义。如果未指定密钥,生产者将使用循环方式在所有主题相关分区之间发送消息;如果指定了密钥,则分区器会处理密钥模块的哈希值和分区数,这样具有相同密钥的消息就会发送到同一分区。因为 Kafka 保证分区级别(而不是主题级别)的排序,所以这也是使所有具有相同键的消息位于同一分区中的一种方法,因此消费者按照发送的顺序接收消息。最后,发送消息的另一种可能的方式是生产者指定分区目的地:在这种情况下没有键,没有循环,但消息被准确地发送到生产者本身指定的分区。