kafka defaultpartitioner算法

kognpnkq  于 2021-06-07  发布在  Kafka
关注(0)|答案(3)|浏览(258)

Kafka有一个非常小但非常有力的细节 org.apache.kafka.clients.producer.internals.DefaultPartitioner 这让我很烦。
这是一行代码:

return DefaultPartitioner.toPositive(Utils.murmur2(keyBytes)) % numPartitions;

更准确地说,最后 % numPartitions . 我一直在问自己,通过使分区id成为现有分区数的函数,引入如此巨大的约束的原因是什么?只是为了方便拥有小数字(人类可读/可追踪?!)与分区总数相比?这里有人对这个问题有更广泛的见解吗?
我这样问是因为在我们的实现中,我们用来在kafka中存储数据的密钥是域敏感的,我们使用它从kafka中检索信息。例如,我们有一些消费者只需要订阅他们感兴趣的分区,而我们进行链接的方式就是使用这些键。
使用不执行模运算的自定义分区器是安全的吗?我们是否应该注意到任何性能下降。这对生产者和/或消费者有什么影响吗?
欢迎任何意见和评论。

rseugnpd

rseugnpd1#

Kafka主题中的分区从 0...N . 因此,如果对密钥进行哈希处理以确定分区,则结果哈希值必须在间隔内 [0;N] --它必须是有效的分区号。
使用模运算是散列中的标准技术。

whlutmcx

whlutmcx2#

使用自定义分区器对性能的影响完全取决于它的实现。
不过,我不太清楚你想达到什么目的。如果我正确理解您的问题,您想直接使用消息键的值作为分区号,而不对其执行任何模运算来确定分区吗?
在这种情况下,您需要做的就是为 ProducerRecord(java.lang.String topic, java.lang.Integer partition, K key, V value) 在向Kafka主题生成消息时,传入所需的分区号。这样,所有默认分区逻辑都将被完全绕过,消息将转到指定的分区。

gupuwyp2

gupuwyp23#

通常对散列进行模运算,以确保条目符合散列范围。
假设哈希范围为5。

-------------------                                                                                   
| 0 | 1 | 2 | 3 | 4 |                                                                                  
 -------------------

如果你输入的hashcode恰好是 6 你必须除以可用的
使其适合范围的桶,在本例中是指桶1。
更重要的是,当你决定添加或删除范围桶。
假设您将hashmap的大小减少到4个bucket,那么最后一个bucket将处于非活动状态,并且
您必须将存储桶4中的值按顺时针方向重新刷新到下一个存储桶(我在说
关于一致性哈希)
另外,新的散列需要在活动的4个bucket中分布,因为第5个bucket将消失,这由模处理。
在分布式系统中,当您向集群中添加或删除节点时,会使用相同的概念来重新灰化。
Kafka的默认partitiononer使用模也是为了同样的目的。如果您添加或删除分区,这是非常常见的情况,如果您问我,例如在大量传入消息期间,我可能希望添加更多分区,以便实现高写吞吐量和高读吞吐量,因为我可以并行使用分区。
您可以根据业务逻辑重写分区算法,方法是选择消息中的某个键,以确保消息在[0…n]范围内均匀分布

相关问题