Java, Apache Kafka에서 주제의 메시지 수를 얻는 방법


93

메시징에 Apache kafka를 사용하고 있습니다. 저는 생산자와 소비자를 Java로 구현했습니다. 주제의 메시지 수를 어떻게 얻을 수 있습니까?

답변:


34

소비자의 관점에서 이것을 염두에 두는 유일한 방법은 실제로 메시지를 소비하고 그 다음 카운트하는 것입니다.

Kafka 브로커는 시작 이후 수신 된 메시지 수에 대한 JMX 카운터를 노출하지만 이미 얼마나 많은 메시지가 제거되었는지 알 수 없습니다.

대부분의 일반적인 시나리오에서 Kafka의 메시지는 무한 스트림으로 가장 잘 보이며 현재 디스크에 보관되는 개별 값을 얻는 것은 관련이 없습니다. 더욱이 토픽에서 메시지의 하위 집합을 모두 가지고있는 브로커 클러스터를 다룰 때 상황이 더 복잡해집니다.


내 대답 stackoverflow.com/a/47313863/2017567을 참조하십시오 . Java Kafka 클라이언트는 해당 정보를 얻을 수 있습니다.
Christophe Quintard 2018-06-22

96

Java는 아니지만 유용 할 수 있습니다.

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

12
이것은 파티션 합계 당 가장 이른 오프셋과 최신 오프셋의 차이가 아니어야합니까? bash-4.3# $KAFKA_HOME/bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list 10.35.25.95:32774 --topic test-topic --time -1 | awk -F ":" '{sum += $3} END {print sum}' 13818663 bash-4.3# $KAFKA_HOME/bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list 10.35.25.95:32774 --topic test-topic --time -2 | awk -F ":" '{sum += $3} END {print sum}' 12434609 그런 다음 차이점은 topic?에서 실제 보류중인 메시지를 반환합니다. 제가 맞습니까?
kisna

1
네, 사실입니다. 가장 빠른 오프셋이 0이 아닌 경우 차이를 계산해야합니다.
ssemichev

그것이 내가 생각했던 거죠 :).
kisna

1
코드 (JAVA, Scala 또는 Python) 내에서 API로 사용하는 방법이 있습니까?
salvob

다음은 내 코드와 Kafka의 코드를 혼합 한 것입니다. 유용 할 수 있습니다. 카프카 통합 KafkaClient - 나는 스파크가 스트리밍을 사용 gist.github.com/ssemichev/c2d94dce7ad65339c9637e1b461f86cf KafkaCluster gist.github.com/ssemichev/fa3605c7b10cb6c7b9c8ab54ffbc5865
ssemichev

17

나는 실제로 이것을 내 POC 벤치마킹에 사용합니다. ConsumerOffsetChecker를 사용하려는 항목입니다. 아래와 같이 bash 스크립트를 사용하여 실행할 수 있습니다.

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

결과는 다음과 같습니다 여기에 이미지 설명 입력 . 빨간색 상자에서 볼 수 있듯이 999는 현재 주제에있는 메시지 수입니다.

업데이트 : ConsumerOffsetChecker는 0.10.0부터 더 이상 사용되지 않으므로 ConsumerGroupCommand 사용을 시작하는 것이 좋습니다.


1
ConsumerOffsetChecker는 더 이상 사용되지 않으며 0.9.0 이후 릴리스에서 삭제됩니다. 대신 ConsumerGroupCommand를 사용하십시오. (kafka.tools.ConsumerOffsetChecker $)
인 Szymon Sadło

1
그래, 내가 말한거야.
Rudy

마지막 문장이 정확하지 않습니다. 위의 명령은 여전히 ​​0.10.0.1에서 작동하며 경고는 이전 설명과 동일합니다.
Szymon Sadło

14

예를 들어 사용자 지정 파티 셔 너를 테스트 할 때 각 파티션의 메시지 수를 아는 데 관심이 있습니다. 다음 단계는 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

행 수는 토픽의 파티션 수에 따라 더 많거나 적을 수 있습니다.


4
로그 압축이 활성화 된 경우 파티션의 오프셋을 합산하면 주제의 정확한 메시지 수가 제공되지 않을 수 있습니다.

14

이후 ConsumerOffsetChecker더 이상 지원되지 않습니다, 당신은 항목의 모든 메시지를 확인하려면이 명령을 사용할 수 없습니다 :

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

LAG토픽 파티션의 메시지 수는 어디에 있습니까?

여기에 이미지 설명 입력

또한 kafkacat을 사용해 볼 수 있습니다 . 이것은 토픽과 파티션에서 메시지를 읽고 stdout으로 출력하는 데 도움이 될 수있는 오픈 소스 프로젝트입니다. 다음은 sample-kafka-topic주제 에서 마지막 10 개의 메시지를 읽은 다음 종료 하는 샘플입니다 .

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

11

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;

이 도구는 좋지만 주제에 점이 2 개 이상 있으면 작동하지 않습니다.
armandfp

7

주제의 모든 파티션에서 처리되지 않은 메시지를 가져 오는 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

5

주제에 대해 저장된 모든 메시지를 얻으려면 각 파티션에 대한 스트림의 시작과 끝까지 소비자를 찾고 결과를 합산 할 수 있습니다.

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());

1
btw, 압축을 켠 경우 스트림에 간격이있을 수 있으므로 실제 메시지 수가 여기에서 계산 된 총계보다 적을 수 있습니다. 정확한 총계를 얻으려면 메시지를 재생하고 개수를 계산해야합니다.
AutomatedMike

5

다음을 실행하십시오 ( 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"

참고 : 나는를 제거되지 --new-consumer해당 옵션을 더 이상 사용할 수 (또는 분명히 필요)이기 때문에
StephenBoesch

3

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

나는 당신이 당신의 대답은 엉망하지 않기 때문에 @AutomatedMike 응답에 비해 답변을 선호 seekToEnd(..)하고 seekToBeginning(..)의 상태를 변경하는 방법 consumer.
adaslaw

2

Kafka Manager의 최신 버전에는 Summed Recent Offsets 라는 열이 있습니다.

여기에 이미지 설명 입력


2

나는 똑같은 질문을했고 이것이 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()

방금이 작업을 수행했지만 기본적으로 끝 오프셋에서 주제의 시작 오프셋을 빼고 싶을 때 이것이 주제에 대한 현재 메시지 개수가됩니다.

주제에서 오래된 메시지를 삭제할 수있는 다른 구성 (정리 정책, 보존 시간 등)으로 인해 끝 오프셋에만 의존 할 수 없습니다. 앞으로 "이동"만 오프셋하므로 끝 오프셋에 더 가깝게 앞으로 이동하는 시작 오프셋입니다 (또는 주제에 지금 메시지가없는 경우 결국 동일한 값으로 이동).

기본적으로 끝 오프셋은 해당 주제를 통과 한 전체 메시지 수를 나타내며, 둘의 차이는 현재 주제에 포함 된 메시지 수를 나타냅니다.


0

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

0

서버의 JMX 인터페이스에 액세스 할 수있는 경우 시작 및 끝 오프셋은 다음 위치에 있습니다.

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

( TOPICNAME& 를 교체해야합니다 PARTITIONNUMBER). 곰 염두에 주어진 파티션의 복제본의 각각에 대해 확인해야하거나 브로커 중 하나가 리더가에 대한 어떤 알아낼 필요 주어진 파티션 (이 시간이 지남에 따라 변경 될 수 있습니다).

또는 Kafka Consumer 메서드 beginningOffsetsendOffsets.


-1

나는 이것을 직접 시도하지 않았지만 말이되는 것 같습니다.

kafka.tools.ConsumerOffsetChecker( source )를 사용할 수도 있습니다 .



-1

kafkatool을 사용할 수 있습니다 . 이 링크를 확인하십시오-> http://www.kafkatool.com/download.html

Kafka Tool은 Apache Kafka 클러스터를 관리하고 사용하기위한 GUI 애플리케이션입니다. Kafka 클러스터 내의 개체와 클러스터의 주제에 저장된 메시지를 빠르게 볼 수있는 직관적 인 UI를 제공합니다.여기에 이미지 설명 입력

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.