[英]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.