繁体   English   中英

计算存储在 kafka 主题中的消息数

[英]Counting Number of messages stored in a kafka topic

我正在使用 0.9.0.0 版本的 Kafka,我想在不使用管理脚本 kafka-console-consumer.sh 的情况下计算主题中的消息数。

我已经尝试了答案Java, How to get number of messages in a topic in apache kafka中的所有命令,但没有一个产生结果。 有人可以帮我从这里出去吗?

您可以尝试执行以下命令:

bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list localhost:9092,localhost:9093,localhost:9094 --topic test-topic --time -1

然后,总结每个分区的所有计数。

更新:Java 实现

Properties props = new Properties();
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
......
try (final KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props)) {
    consumer.subscribe(Arrays.asList("your_topic"));
    Set<TopicPartition> assignment;
    while ((assignment = consumer.assignment()).isEmpty()) {
        consumer.poll(Duration.ofMillis(100));
    }
    final Map<TopicPartition, Long> endOffsets = consumer.endOffsets(assignment);
    final Map<TopicPartition, Long> beginningOffsets = consumer.beginningOffsets(assignment);
    assert (endOffsets.size() == beginningOffsets.size());
    assert (endOffsets.keySet().equals(beginningOffsets.keySet()));

    Long totalCount = beginningOffsets.entrySet().stream().mapToLong(entry -> {
            TopicPartition tp = entry.getKey();
            Long beginningOffset = entry.getValue();
            Long endOffset = endOffsets.get(tp);
            return endOffset - beginningOffset;
        }).sum();
    System.out.println(totalCount);
}

从技术上讲,您可以简单地使用来自主题的所有消息并计算它们:

例子:

kafka-run-class.sh kafka.tools.SimpleConsumerShell --broker-list localhost:9092 --topic XYZ --partition 0*

然而kafka.tools.GetOffsetShell方法会给你偏移量而不是主题中的实际消息数。 这意味着如果主题被压缩,如果您通过使用消息或读取偏移量来计算消息,您将获得两个不同的数字。

主题压缩: https : //kafka.apache.org/documentation.html#design_compactionbasics

您可以使用以下方法总结所有计数:

.../bin/kafka-run-class kafka.tools.GetOffsetShell --broker-list <<broker_1>>:9092,<<broker_2:9092>>... --topic <<your_topic_name>> --time -1 | while IFS=: read topic_name partition_id number; do echo "$number"; done | paste -sd+ - | bc

你也可以使用 awk 和一个简单的循环来做到这一点

for i in `kafka-run-class kafka.tools.GetOffsetShell --broker-list broker:9092 --time -1 --topic topic_name| awk -F : '{print $3}'`; do sum=$(($sum+$i)); done

如果您不想为“原始”Kafka 脚本带来麻烦,那么还有kafkacat

基本思想是

  • 消耗每个分区的最后一条消息并
  • 将偏移量相加(校正基于零的偏移量)。

让我们开发这个。

kafkacat -C -b <broker> -t <topic> -o -1 -f '%p\t%o\n'

这将输出如下内容(加上 stderr 上的“到达分区结束”通知):

0    77
1    75
2    78

现在, kafkacat不会终止,而是一直在等待新消息。 我们可以通过添加超时来避免这种情况(选择一​​个足够大的值,以便您获得给定环境中的所有分区):

timeout --preserve-status 1 kafkacat <snip>

现在,我们可以继续前进,加起来第二列(+1个) -但如果超时时间内,有新的消息,我们可以得到这样的:

0    77
1    75
2    78
1    76

所以我们必须考虑到这一点,这很容易用一点awk来完成:

timeout --preserve-status 1 kafkacat <snip> 2> /dev/null \
| awk '{lastOffsets[$1] = $2} END {count = 0; for (i in lastOffsets) { count += lastOffsets[i] + 1 }; print count}'

请注意我们如何使用(散列)映射来记住每个分区最后看到的偏移量,直到超时触发,然后遍历数组以计算总和。

我们可以使用下面的简单java来获取有关主题的消息数

Properties props = new Properties();
props.setProperty("bootstrap.servers", "localhost:9091");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
List<PartitionInfo> parts = consumer.partitionsFor("topic");
List<TopicPartition> partitions= new ArrayList<>();
for (PartitionInfo p : parts) {
            partitions.add(new TopicPartition(topic, p.partition()));
        }
consumer.assign(partitions);        

Map<TopicPartition, Long> endOffsets = consumer.endOffsets(assignment);
Map<TopicPartition, Long> beginningOffsets = consumer.beginningOffsets(assignment);
long totalMessaheCnt=0;
for (TopicPartition tp : offsets.keySet()) {
totalMessaheCnt += endOffsets.get(tp)-beginningOffsets.get(tp)
}

获取主题中的记录数

brokers="<broker1:port>"
topic=<topic-name>
sum_1=$(/usr/hdp/current/kafka-broker/bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list $brokers --topic $topic --time -1 | grep -e ':[[:digit:]]*:' | awk -F  ":" '{sum += $3} END {print sum}')
sum_2=$(/usr/hdp/current/kafka-broker/bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list $brokers --topic $topic --time -2 | grep -e ':[[:digit:]]*:' | awk -F  ":" '{sum += $3} END {print sum}')
echo "Number of records in topic ${topic}: "$((sum_1 - sum_2))

我们可以使用kafkacat命令来统计一个主题中的消息数量。 命令如下。 请注意,即使您的消息是多行的,此命令也将起作用。

kafkacat -b <broker_1_ip:port>,<broker_2_ip:port> -t <topic-name> -C -e -q -f 'Offset: %o\n' | wc -l

从控制台上打印的数字中减去 1,这就是答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM