迫使kafka用户以最高的延迟轮询分区

时间:2019-12-27 11:16:37

标签: java scala apache-kafka kafka-consumer-api

我有一个设置,其中几个KafkaConsumers每个处理一个主题上的多个分区。为它们静态分配了分区,以确保每个使用者都有相同数量的分区要处理。还选择了记录密钥,以便我们在所有分区上均等地分配消息。

在负载很重的时候,我们经常会看到少量的分区积累了相当大的滞后时间(成千上万条消息/数分钟的时间),而其他负载相同并且由相同使用者使用的分区却设法将延迟降低到几百条消息/几秒钟。

看来,消费者正在尽可能快地获取记录,遍历大多数分区,但是现在不时有一个分区被长时间搁置。理想情况下,我希望看到延迟在各个分区之间更均匀地分布。

一段时间以来,我一直在阅读有关KafkaConsumer轮询行为和配置的信息,到目前为止,我认为有两种方法可以解决此问题:

  1. 构建一些自定义的东西,可以监视每个分区的滞后,并使用KafkaConsumer.pause().resume()来强制KafkaConsumer从滞后最大的分区中读取
  2. 限制我们的KafkaConsumer只订阅一个TopicPartition,并使用KafkaConsumer的多个实例。

这些选项似乎都不是处理此问题的正确方法。配置似乎也没有答案:

  • max.partition.fetch.bytes仅指定单个分区的最大读取大小,并不保证下一次获取将来自另一个分区。
  • max.poll.interval.ms仅适用于消费者群体,不适用于每个分区。

我是否缺少鼓励KafkaConsumer频繁切换分区的方法?还是对延迟最大的分区实施首选项的方法?

1 个答案:

答案 0 :(得分:0)

不确定答案是否仍然与您相关,或者我的答案是否完全满足您的需求,但是,您可以尝试使用滞后意识分配器。这个为消费者分配分区的分配器确保为消费者分配分区,以便均匀/平等地分配消费者之间的滞后。这是我使用的编写良好的代码,它实现了基于滞后的分配器。

https://github.com/grantneale/kafka-lag-based-assignor

您需要做的就是配置您的消费者以使用此分配器。以下声明。

props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG, LagBasedPartitionAssignor.class.getName());