默认的 Kafka 分区器创建散列键冲突

The default Kafka partitioner create hash key collision

我有一个包含 10 个分区的主题,并且我已经使用 A,B,C,D,E,F,G,H,I 9 个不同的键生成事件。

我观察到消息这样做:

Partition 0- (Message1, Key E), (Message2, Key I)
Partition 1- (Message3, Key F) 
. 
. 
Partition7-(Message4, Key A), (Message5, Key A)
Partition8- Empty 
Partition9- Empty

同一个分区有2条不同key的消息,也有空分区。

Kafka 默认 partitioner 会产生冲突吗?

我正在从一个平衡到两个默认其余部分的流中生成 producers

这就是我所期待的:

 Partition 0- (Message1, Key E)
 Partition 1- (Message3, Key F) 
 . 
 . 
 Partition7-(Message4, Key A), (Message5, Key A)
 Partition8-(Message2, Key I) 
 Partition9- Empty

Kafka 的 DefaultPartitioner 在生产者客户端使用 murmur 哈希算法为每个消息分配一个分区。不能保证10个分区和个位数的key会均匀分布。每个消息的分区计算是相互独立的,碰撞概率是一个数学兴趣。

编辑:

杂音哈希算法不太可能导致冲突。 Kafka 主题中的分区是固定的 - 它不能像 java HashMap 实现中的桶大小那样增长。因此,分区算法使用一个计算分区数模数的公式。确切的公式是 Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;

现在您可以看到,如果 hash mod number of partitions 产生相同的值,那么两个不同的键确实可以产生相同的分区号。

对于大量的随机密钥集,密钥将在所有分区中均匀分布。

如果你想排序,那么你必须使用分区键..在这种情况下,你对冲突和空分区的担忧几乎没有实际后果(好吧,对于大量随机键,它们会没问题)。 如果您假设 Kafka 会集中确保先填充空分区,然后再将密钥路由到已填充的分区,那不是工作原理

是的,默认的分区程序会产生冲突,并且最迟会在您的密钥多于分区时发生。请参阅@senseiwu 的答案,它很好地解释了会发生什么。 如果您有一组有限的密钥并希望将它们分布在相同数量的分区上,您必须实现自己的分区程序。