我有一个分区主题,它有X
个分区。
截至目前,在生成消息时,我创建了 Kafka 的ProducerRecord
,仅指定topic
和value
。我不定义key
. 据我了解,我的消息将使用默认的内置分区程序在分区之间均匀分布。 另一方面,我有一个 Kafka 消费者的线程池。每个 Kafka 使用者都将在自己的专用线程中运行,使用来自主题的消息。这些消费者中的每一个都被赋予相同的group.id
。这将允许并行使用消息。每个使用者都将被分配其公平份额的分区进行读取。
我希望我的消息以有序的方式使用。我知道 Kafka 保证分区内消息的顺序。因此,只要我想出一个正确的键结构,我就会对我的消息进行分区,使它们最终位于同一分区中。在某种程度上,消息密钥对消息进行分组并将它们存储在分区中。
有意义吗?
问:是否有可能由于密钥设计不当而导致分区不均匀?一个人可能收到比其他人更多的记录。它会严重影响我的 Kafka 集群的性能吗?消息密钥设计的最佳实践是什么?
您对默认分区程序的理解是正确的。
如果您不需要按照生成消息的相同顺序使用某些消息,则不指定密钥是最佳选择。如果这不是您的情况,那么您的要求会告诉您什么是您的密钥。例如,如果要保留给定用户生成的消息的顺序,则user_id可能是您的消息密钥。
要实现特定的消息顺序,您需要考虑如何配置生产者。如果您的生产者可以在失败时重试发送消息,并且in flight messages
大于 1,则消息可能会无序生成。
您可以通过指定错误键来获得不均匀的分区。例如,如果 90% 的用户来自纽约,10% 来自其他城市,并且您选择一个城市作为键,那么您的一个分区将很大,其中一个消费者过载(我假设每个用户的消息数量相同(。
Kafka 将在键上应用 murmur 哈希,并使用分区数进行模处理,因此它即 murmur2(record.key(((( % num 分区。在所有可能的引擎盖中,在默认分区的情况下,它应该均匀分布。我建议您使用用java编写的简单murmur2函数来试验所有关键选项,以查看分布模式,然后做出选择。 在 kafka 中还有两种默认分区的实现。杂音哈希实现在较新版本中。旧的旧版本的工作方式不同。