簡體   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