默认的Kafka分区器会创建哈希键冲突。

3

我有一个包含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

在同一分区中有两个不同密钥的消息,也有空分区。
Kafka的默认分区器是否会创建冲突?
我从一个流中生产,该流平衡到两个默认的rest 生产者
这就是我期望的:
 Partition 0- (Message1, Key E)
 Partition 1- (Message3, Key F) 
 . 
 . 
 Partition7-(Message4, Key A), (Message5, Key A)
 Partition8-(Message2, Key I) 
 Partition9- Empty
2个回答

10
Kafka的DefaultPartitioner在生产者客户端使用murmur哈希算法为每个消息分配一个分区。对于10个分区和单个数字键,没有保证它们将均匀分布。每个消息的分区计算是相互独立的,碰撞的概率是数学上的兴趣。

编辑:

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

现在你可以看到,如果hash mod number of partitions得到相同的值,则两个不同的密钥确实可以得到相同的分区号。

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

如果您想要进行排序,那么必须使用分区键。在这种情况下,关于碰撞和空分区的担忧实际上并没有太大的影响(对于一组大量的随机键而言,它们将是可以接受的)。如果您认为 Kafka 会在将键路由到已经填充的分区之前首先确保填充空分区,那么事实并非如此。

1
拥有会产生冲突的哈希的目的是什么?有没有任何指南可以帮助选择不会发生碰撞的关键字? - undefined
@Dipperman,根据定义,哈希函数应该会产生冲突(https://en.wikipedia.org/wiki/Hash_function)。 - undefined
@wardziniak 我知道哈希在定义上可以产生冲突,但我不明白为什么在Kafka中我们需要冲突?没有冲突会均匀分布。 - undefined
1
如果你想均匀分布,请省略键和默认的分区器将使用轮询进行分区。 - undefined
在这种情况下,我将会有均匀但无序的结果。我需要根据其关键字对事件进行排序。 - undefined

1

默认的分区器会创建冲突,最晚在你拥有比分区数多一个键时会发生。请参考@senseiwu的答案,他很好地解释了会发生什么。 如果你有一组有限的键,并且想要将它们分布在相同数量的分区上,你必须实现自己的分区器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接