簡體   English   中英

Java,如何在 apache kafka 中獲取主題中的消息數

[英]Java, How to get number of messages in a topic in apache kafka

我正在使用 apache kafka 進行消息傳遞。 我已經用 Java 實現了生產者和消費者。 我們如何獲取主題中的消息數?

它不是java,但可能有用

./bin/kafka-run-class.sh kafka.tools.GetOffsetShell \
  --broker-list <broker>:<port> \
  --topic <topic-name> \
  | awk -F  ":" '{sum += $3} END {print sum}'

從消費者的角度來看,對此想到的唯一方法是實際使用消息並隨后對其進行計數。

Kafka 代理公開了自啟動以來收到的消息數量的 JMX 計數器,但您無法知道其中有多少已被清除。

在最常見的情況下,Kafka 中的消息最好被視為無限流,並且獲取當前保留在磁盤上的數量的離散值是不相關的。 此外,當處理在一個主題中都有一個消息子集的代理集群時,事情會變得更加復雜。

由於不再支持ConsumerOffsetChecker ,您可以使用此命令檢查主題中的所有消息:

bin/kafka-run-class.sh kafka.admin.ConsumerGroupCommand \
    --group my-group \
    --bootstrap-server localhost:9092 \
    --describe

其中LAG是主題分區中的消息數:

在此處輸入圖像描述

您也可以嘗試使用kafkacat 這是一個開源項目,可以幫助您從主題和分區中讀取消息並將它們打印到標准輸出。 這是一個示例,它從sample-kafka-topic主題中讀取最后 10 條消息,然后退出:

kafkacat -b localhost:9092 -t sample-kafka-topic -p 0 -o -10 -e

我實際上用它來對我的 POC 進行基准測試。 您要使用 ConsumerOffsetChecker 的項目。 您可以使用如下所示的 bash 腳本運行它。

bin/kafka-run-class.sh kafka.tools.ConsumerOffsetChecker  --topic test --zookeeper localhost:2181 --group testgroup

結果如下: 在此處輸入圖像描述 正如您在紅色框中看到的那樣,999 是當前主題中的消息數。

更新:ConsumerOffsetChecker 自 0.10.0 起已棄用,您可能希望開始使用 ConsumerGroupCommand。

有時感興趣的是了解每個分區中的消息數量,例如,在測試自定義分區器時。隨后的步驟已經過測試,可與 Confluent 3.2 中的 Kafka 0.10.2.1-2 一起使用。 給定一個 Kafka 主題、 kt和以下命令行:

$ kafka-run-class kafka.tools.GetOffsetShell \
  --broker-list host01:9092,host02:9092,host02:9092 --topic kt

打印示例輸出,顯示三個分區中的消息計數:

kt:2:6138
kt:1:6123
kt:0:6137

行數可能或多或少取決於主題的分區數。

使用https://prestodb.io/docs/current/connector/kafka-tutorial.html

Facebook 提供的一個超級 SQL 引擎,它連接多個數據源(Cassandra、Kafka、JMX、Redis ...)。

PrestoDB 作為帶有可選工作程序的服務器運行(有一個沒有額外工作程序的獨立模式),然后您使用一個小的可執行 JAR(稱為 presto CLI)進行查詢。

配置好 Presto 服務器后,就可以使用傳統的 SQL:

SELECT count(*) FROM TOPIC_NAME;

Apache Kafka 命令在主題的所有分區上獲取未處理的消息:

kafka-run-class kafka.tools.ConsumerOffsetChecker 
    --topic test --zookeeper localhost:2181 
    --group test_group

印刷:

Group      Topic        Pid Offset          logSize         Lag             Owner
test_group test         0   11051           11053           2               none
test_group test         1   10810           10812           2               none
test_group test         2   11027           11028           1               none

第 6 列是未處理的消息。 像這樣添加它們:

kafka-run-class kafka.tools.ConsumerOffsetChecker 
    --topic test --zookeeper localhost:2181 
    --group test_group 2>/dev/null | awk 'NR>1 {sum += $6} 
    END {print sum}'

awk 讀取行,跳過標題行並將第 6 列相加,最后打印總和。

印刷

5

使用 Kafka 2.11-1.0.0 的 Java 客戶端,您可以執行以下操作:

    KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
    consumer.subscribe(Collections.singletonList("test"));
    while(true) {
        ConsumerRecords<String, String> records = consumer.poll(100);
        for (ConsumerRecord<String, String> record : records) {
            System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());

            // after each message, query the number of messages of the topic
            Set<TopicPartition> partitions = consumer.assignment();
            Map<TopicPartition, Long> offsets = consumer.endOffsets(partitions);
            for(TopicPartition partition : offsets.keySet()) {
                System.out.printf("partition %s is at %d\n", partition.topic(), offsets.get(partition));
            }
        }
    }

輸出是這樣的:

offset = 10, key = null, value = un
partition test is at 13
offset = 11, key = null, value = deux
partition test is at 13
offset = 12, key = null, value = trois
partition test is at 13

運行以下命令(假設kafka-console-consumer.sh在路徑上):

kafka-console-consumer.sh  --from-beginning \
--bootstrap-server yourbroker:9092 --property print.key=true  \
--property print.value=false --property print.partition \
--topic yourtopic --timeout-ms 5000 | tail -n 10|grep "Processed a total of"

要獲取為主題存儲的所有消息,您可以將消費者尋找到每個分區的流的開頭和結尾,並對結果求和

List<TopicPartition> partitions = consumer.partitionsFor(topic).stream()
        .map(p -> new TopicPartition(topic, p.partition()))
        .collect(Collectors.toList());
    consumer.assign(partitions); 
    consumer.seekToEnd(Collections.emptySet());
Map<TopicPartition, Long> endPartitions = partitions.stream()
        .collect(Collectors.toMap(Function.identity(), consumer::position));
    consumer.seekToBeginning(Collections.emptySet());
System.out.println(partitions.stream().mapToLong(p -> endPartitions.get(p) - consumer.position(p)).sum());

我有同樣的問題,這就是我在 Kotlin 中來自 KafkaConsumer 的做法:

val messageCount = consumer.listTopics().entries.filter { it.key == topicName }
    .map {
        it.value.map { topicInfo -> TopicPartition(topicInfo.topic(), topicInfo.partition()) }
    }.map { consumer.endOffsets(it).values.sum() - consumer.beginningOffsets(it).values.sum()}
    .first()

非常粗略的代碼,因為我剛剛開始工作,但基本上你想從結束偏移中減去主題的開始偏移,這將是主題的當前消息計數。

您不能僅僅依賴結束偏移量,因為其他配置(清理策略、保留毫秒等)可能最終導致從您的主題中刪除舊消息。 偏移量僅向前“移動”,因此它是開始偏移量將向前移動更接近結束偏移量(或者最終到相同的值,如果主題現在不包含消息)。

基本上,結束偏移量表示通過該主題的消息總數,兩者之間的差異表示該主題現在包含的消息數。

在最新版本的 Kafka Manager 中,有一列標題為Summed Recent Offsets

在此處輸入圖像描述

Kafka 文檔節選

0.9.0.0 中的棄用

kafka-consumer-offset-checker.sh (kafka.tools.ConsumerOffsetChecker) 已被棄用。 今后,請使用 kafka-consumer-groups.sh (kafka.admin.ConsumerGroupCommand) 來實現此功能。

我正在為服務器和客戶端運行啟用 SSL 的 Kafka 代理。 下面的命令我使用

kafka-consumer-groups.sh --bootstrap-server Broker_IP:Port --list --command-config /tmp/ssl_config kafka-consumer-groups.sh --bootstrap-server Broker_IP:Port --command-config /tmp/ssl_config --describe --group group_name_x

其中 /tmp/ssl_config 如下

security.protocol=SSL
ssl.truststore.location=truststore_file_path.jks
ssl.truststore.password=truststore_password
ssl.keystore.location=keystore_file_path.jks
ssl.keystore.password=keystore_password
ssl.key.password=key_password

如果您有權訪問服務器的 JMX 接口,則開始和結束偏移量位於:

kafka.log:type=Log,name=LogStartOffset,topic=TOPICNAME,partition=PARTITIONNUMBER
kafka.log:type=Log,name=LogEndOffset,topic=TOPICNAME,partition=PARTITIONNUMBER

(您需要替換TOPICNAMEPARTITIONNUMBER )。 請記住,您需要檢查給定分區的每個副本,或者您需要找出哪個代理是給定分區的領導者(這可能會隨着時間而改變)。

或者,您可以使用Kafka Consumer方法beginningOffsetsendOffsets

我們可以使用下面的簡單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)
}

如果您需要為一個消費者組中的所有消費者(或不同消費者組)計算結果,另一種選擇是使用管理客戶端並從主題/分區偏移量中減去消費者組偏移量,Kotlin 中的代碼示例:

val topicName = "someTopic"
val groupId = "theGroupId"
val admin = Admin.create(kafkaProps.buildAdminProperties()) // Spring KafkaProperties
val parts = admin.describeTopics(listOf(topicName)).values()[topicName]!!.get().partitions()
val topicPartitionOffsets = admin.listOffsets(parts.associate { TopicPartition(topicName, it.partition()) to OffsetSpec.latest() }).all().get()
val consumerGroupOffsets = admin.listConsumerGroupOffsets(groupId)
    .partitionsToOffsetAndMetadata().get()
val highWaterMark = topicPartitionOffsets.map { it.value.offset() }.sum()
val consumerPos = consumerGroupOffsets.map { it.value.offset() }.sum()
val unProcessedMessages = highWaterMark - consumerPos

此外,這里是 LeYAUable 示例代碼的工作版本,它僅使用常規(非管理員)客戶端:

val partitions = consumer.partitionsFor("topicName")
        .map { TopicPartition(it.topic(), it.partition()) }
val highWaterMark = consumer.endOffsets(partitions).values.sum()
val consumerPosition = consumer.beginningOffsets(partitions).values.sum()
val msgCount = highWaterMark - consumerPosition

不過,這只會為您提供此特定消費者的偏移量! 通常需要注意的是,在壓縮主題時這是不精確的。

我自己沒有嘗試過, 但這似乎是有道理的。

您還可以使用kafka.tools.ConsumerOffsetChecker ( source )。

我發現最簡單的方法是使用 Kafdrop REST API /topic/topicName並指定 key: "Accept" / value: "application/json"標頭以獲取 JSON 響應。

這在此處記錄

您可以使用kafkatool 請檢查此鏈接-> http://www.kafkatool.com/download.html

Kafka Tool 是一個用於管理和使用 Apache Kafka 集群的 GUI 應用程序。 它提供了一個直觀的 UI,允許人們快速查看 Kafka 集群中的對象以及存儲在集群主題中的消息。 在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM