我在kafka中遇到了一个负载平衡的问题。因此,我创建了一个包含10个分区的主题,并创建了2个使用者。这10个分区被划分并分配给这些用户(5个分区分配给第一个用户,5个分区分配给第二个用户),工作正常。有时第一消费者工作,有时第二消费者工作。
但在某一时刻,我们可能会遇到这样一种情况:例如,第二个消费者收到一条消息,处理该消息需要时间(例如10分钟)。
所以,我的问题是Kafka将如何决定将消息存储到哪个分区?
在这种情况下,我认为循环不是一个好主意,因为分区中由第二个使用者处理的消息在第二个使用者完成长时间的工作之前不会被处理。
更新了!
根据@millan baran的回答,生产方的负荷是平衡的。但在这种情况下,即使我们提供了一个自定义 Partitioner
实现时,同样的问题是,在分配给正在执行长期工作的使用者的分区中存储的消息在该使用者完成其长期工作之前不会被处理。
可能,还有其他地方的负载平衡器?
3条答案
按热度按时间a64a0gku1#
谢谢大家的帮助。但我找到了问题的答案。所以首先,Kafka至少有3个地方可以平衡负载:
要将分区分配给使用者,可以使用“循环”或“范围”算法。这可以通过设置
partition.assignment.strategy
财产。默认情况下,使用范围。在生产者级别,可以应用一种选择分区来存储消息的策略。这可以通过
partitioner.class
以及我问题的答案。如果一个消费者处理消息很长时间,kafka会认为这个消费者已经死了,并在另一个消费者之间重新分配分区。因此,当使用者完成一项长时间的工作时,不会为其分配任何分区。当使用者完成长时间工作时,将再次为其分配分区。不会有消息挂起。xxhby3vn2#
看来你需要的是排队。一个分区被多个使用者使用。每个使用者从分区中获取一条记录,对其进行处理,然后获取另一条记录。如果一个使用者花费太多时间来处理记录,其他使用者仍然可以从分区中获取(不同的)记录。
然而,Kafka并不支持这一点。每个分区只能由一个使用者组中的一个使用者使用。
一句话,你需要一些别的东西来实现这个目标,比如rabbitmq。
rlcwz9us3#
应该使用哪个分区的决定不取决于kafka,但是发送消息的生产者必须做出决定。看看https://kafka.apache.org/documentation#producerconfigs
您可以提供一个partitioner类来决定选择哪个分区。
分区器类
实现partitioner接口的partitioner类。org.apache.kafka.clients.producer.internals.defaultpartitioner
这里描述了defaultpartitioner策略