默认的 Kafka 分区器创建哈希键冲突
Posted
技术标签:
【中文标题】默认的 Kafka 分区器创建哈希键冲突【英文标题】:The default Kafka partitioner create hash key collision 【发布时间】:2019-05-31 19:26:15 【问题描述】:我有一个包含 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
【问题讨论】:
【参考方案1】:Kafka 的 DefaultPartitioner 在生产者客户端使用murmur 哈希算法为每条消息分配一个分区。不能保证对于 10 个分区和个位数的键,它们会均匀分布。每个消息的分区计算是相互独立的,碰撞概率是一个数学兴趣。
编辑:
杂音哈希算法导致冲突的可能性很小。 Kafka 主题中的分区是固定的 - 它不会像 java HashMap 实现中的桶大小一样增长。因此,分区算法使用计算分区数模的公式。确切的公式是Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
现在您可以看到,如果hash mod number of partitions
产生相同的值,则两个不同的键确实可以产生相同的分区号。
对于大量随机密钥集,密钥将均匀分布在所有分区中。
如果您想要排序,那么您必须使用分区键..在这种情况下,您对冲突和空分区的担忧几乎没有实际后果(好吧,对于大量随机键来说,它们是可以的)。 如果您假设 Kafka 会集中确保在将密钥路由到已填充的分区之前先填充空分区,那么事情就不是这样了
【讨论】:
产生冲突的哈希的目的是什么?有什么指南可以选择不让它们碰撞的键吗? @Dipperman,根据定义,哈希应该会产生冲突 (en.wikipedia.org/wiki/Hash_function) @wardziniak 我知道根据定义散列会产生冲突,但我不明白为什么我们需要在 Kafka 中发生冲突?没有碰撞会均匀分布。 如果要均匀分布,省略key,默认partitioner会使用round-robin进行分区 在这种情况下,我将统一但无序。我需要订购有关其键的事件【参考方案2】:是的,默认分区程序会产生冲突,最迟当您拥有的密钥比您拥有的分区多一个时才会发生冲突。请参阅@senseiwu 的答案,它很好地解释了会发生什么。 如果您有一组有限的键并希望将它们分布在相同数量的分区上,您必须实现自己的分区器。
【讨论】:
以上是关于默认的 Kafka 分区器创建哈希键冲突的主要内容,如果未能解决你的问题,请参考以下文章