假设我有一个无限期运行的计时器任务,该任务遍历kafka集群中的所有使用者组,并为每个组的所有分区输出滞后,已提交的偏移量和结束偏移量。与Kafka控制台使用者群组脚本的工作方式类似,不同之处在于它适用于所有群组。
类似
单个使用者-不起作用-不为某些提供的主题分区返回偏移量(例如,提供了10个-返回了5个偏移量)
Consumer consumer;
static {
consumer = createConsumer();
}
run() {
List<String> groupIds = getConsumerGroups();
for(String groupId: groupIds) {
List<TopicParition> topicParitions = getTopicParitions(groupId);
consumer.endOffsets(topicParitions); -- Not working - missing offsets for some partitions for some groups (in 10 - out 5)
}
}
多个消费者-工作
run() {
List<String> groupIds = getConsumerGroups();
for(String groupId: groupIds) {
List<TopicParition> topicParitions = getTopicParitions(groupId);
Consumer consumer = createConsumer();
consumer.endOffsets(topicParitions); This works!!!
}
}
版本:Kafka-Client 2.0.0
我是否正确使用了消费者api?理想情况下,我想使用单个消费者。
让我知道是否需要更多详细信息。
答案 0 :(得分:1)
我认为您快到了。首先收集所有您感兴趣的主题分区,然后发布一个consumer.endOffsets
命令。
请记住,我还没有尝试运行它,但是这样的方法应该可以工作:
run() {
Consumer consumer = createConsumer();
List<String> groupIds = getConsumerGroups();
List<TopicPartition> topicPartitions = new ArrayList<>();
for (String groupId: groupIds) {
topicPartitions.addAll(getTopicPartitions(groupId));
}
consumer.endOffsets(topicPartitions);
}
答案 1 :(得分:1)
这是Fetcher.fetchOffsetsByTimes()
中的一个错误,特别是在groupListOffsetRequests
方法内部,其中的逻辑是不添加分区以进行重试,而领导者请求分区偏移量则未知或不可用。
当您在所有使用者组分区上使用单个使用者时,这一点尤其明显,在某些情况下,当我们请求endoffsets
时某些组已经具有主题分区领导者信息,而对于没有领导者信息未知或未知的主题分区,由于该错误,无法使用的功能将被取消。
后来,我意识到从每个消费者组中提取主题分区不是一个好主意,而是进行了更改,以从AdminClient.listTopics & AdminClient.describeTopics
中读取主题分区,然后一次全部传递给Consumer.endOffsets
。
尽管这不能完全解决问题,因为在多次运行之间主题/分区可能仍然不可用或未知。
可以找到更多信息-KAFKA-7044
和pull request
。此问题已修复,计划在2.1.0版本中发布。