KafkaProducer循环分发不适用于相同的密钥

时间:2018-01-15 22:54:38

标签: 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));

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

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));

2 个答案:

答案 0 :(得分:2)

这正是Kafka制作人的作品。此行为由您在官方仓库中找到的DefaultPartitionerhere定义。 如果未指定密钥,则生产者使用循环方式在所有与主题相关的分区上发送消息;如果指定了密钥,则分区程序处理密钥模块的散列分区数,并且以这种方式,具有相同密钥的消息进入同一分区。因为Kafka保证在分区级别(而不是主题级别)进行排序,所以这也是使所有具有相同密钥的消息在同一分区中并且消费者以与发送它们相同的顺序接收的方式。 最后,发送消息的另一种可能方式是生产者指定分区目的地:在这种情况下没有密钥,没有循环,但消息被准确地发送到生产者自己指定的分区。

答案 1 :(得分:1)

这是预期的行为。具有相同密钥的所有消息都放在同一分区中。如果要为所有邮件分配循环,则不应提供密钥。对于Kafka来说,获得密钥的原因是在整个分区中分发数据,并将相同的密钥放在不同的分区中会破坏这个合同。