Java, как получить количество сообщений в теме в apache kafka

Я использую apache kafka для обмена сообщениями. Я реализовал производителя и потребителя на Java. Как узнать количество сообщений в теме?

13 ответов


единственный способ, который приходит на ум для этого с точки зрения потребителя, - это фактически потреблять сообщения и подсчитывать их.

брокер Kafka предоставляет счетчики JMX для количества сообщений, полученных с момента запуска, но вы не можете знать, сколько из них уже было очищено.

в большинстве распространенных сценариев сообщения в Kafka лучше всего рассматривать как бесконечный поток и получение дискретного значения того, сколько в настоящее время хранится на диске, не имеет значения. Кроме того, все усложняется при работе с кластером брокеров, у которых есть подмножество сообщений в теме.


Это не Java, но может быть полезным

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

Я действительно использую это для бенчмаркинга моего POC. Элемент, который вы хотите использовать ConsumerOffsetChecker. Вы можете запустить его с помощью bash-скрипт, как показано ниже.

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

и ниже результат : enter image description here Как вы можете видеть на Красном поле, 999-это номер сообщения в данный момент в теме.

Update: ConsumerOffsetChecker устарел с 0.10.0, вы можете начать использовать ConsumerGroupCommand.


использовать https://prestodb.io/docs/current/connector/kafka-tutorial.html

Super SQL engine, предоставляемый Facebook, который подключается к нескольким источникам данных (Cassandra, Kafka, JMX, Redis ...).

PrestoDB работает как сервер с дополнительными рабочими (существует автономный режим без дополнительных рабочих), затем вы используете небольшую исполняемую банку (называемую presto CLI) для выполнения запросов.

Как только вы настроили сервер Presto, вы можете используйте традиционный SQL:

SELECT count(*) FROM TOPIC_NAME;

чтобы получить все сообщения, сохраненные для темы, вы можете искать потребителя в начале и конце потока для каждого раздела и суммировать результаты

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

команда 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 += } 
    END {print sum}'

awk читает строки, пропускает строку заголовка и добавляет 6-й столбец, а в конце печатает сумму.

печать

5

в самых последних версиях Kafka Manager есть столбец под названием Суммированы Последние Смещения.

enter image description here


иногда интерес заключается в том, чтобы знать количество сообщений в каждом разделе, например, при тестировании пользовательского разделителя.Последующие шаги были протестированы для работы с Кафкой 0.10.2.1-2 из Confluent 3.2. Дал Кафка теме 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

количество строк может быть больше или меньше в зависимости от количества разделы для темы.


Я не пробовал этой себя, но, кажется, это имеет смысл.

вы также можете использовать kafka.tools.ConsumerOffsetChecker (источник).


используя Java-клиент Kafka 2.11-1.0.0, вы можете сделать следующее:

    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 --from-beginning --new-consumer --bootstrap-сервер yourbroker: 9092 --печать свойств.key=true --печать свойств.value=false --печать свойств.раздел --тема yourtopic --timeout-ms 5000 / tail-n 10 / grep "обработано в общей сложности"


выдержки из документов Кафки

Deprecations в 0.9.0.0

kafka-consumer-offset-checker.sh (Кафка.инструменты.ConsumerOffsetChecker) является устаревшим. Идя вперед, пожалуйста, используйте kafka-consumer-groups.sh (Кафка.администратор.ConsumerGroupCommand) для этой функции.

Я запускаю Kafka broker с поддержкой SSL как для сервера, так и для клиента. Ниже команды я использую

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

(нужно заменить TOPICNAME & PARTITIONNUMBER). Имейте в виду, что вам нужно проверить каждую из реплик данного раздела, или вам нужно выяснить, какой из брокеров является лидером для дано раздел (и это может меняться с течением времени).

кроме того, вы можете использовать Кафка Потребителя методы beginningOffsets и endOffsets.