Я використовую apache kafka для обміну повідомленнями. Я застосував виробника та споживача на Java. Як ми можемо отримати кількість повідомлень у темі?
Відповіді:
Єдиний спосіб, який для цього приходить на думку з погляду споживача, - це насправді споживати повідомлення та підраховувати їх тоді.
Брокер 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 += $3} END {print sum}'
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
І тоді різниця повертає фактичні повідомлення, що очікують на розгляд у темі? Я прав?
Я фактично використовую це для порівняльного оцінювання мого рівня POC. Елемент, який ви хочете використовувати ConsumerOffsetChecker. Ви можете запустити його за допомогою скрипту bash, як показано нижче.
bin/kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --topic test --zookeeper localhost:2181 --group testgroup
А нижче - результат: Як ви можете бачити на червоному полі, 999 - це кількість повідомлень, що зараз перебувають у темі.
Оновлення: ConsumerOffsetChecker застарілий з 0.10.0, можливо, ви захочете почати використовувати ConsumerGroupCommand.
Іноді інтерес полягає у знанні кількості повідомлень у кожному розділі, наприклад, під час тестування спеціального розділу. Наступні кроки були протестовані для роботи з Kafka 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
Кількість рядків може бути більшою чи меншою залежно від кількості розділів для теми.
Оскільки ConsumerOffsetChecker
більше не підтримується, ви можете використовувати цю команду, щоб перевірити всі повідомлення в темі:
bin/kafka-run-class.sh kafka.admin.ConsumerGroupCommand \
--group my-group \
--bootstrap-server localhost:9092 \
--describe
Де LAG
кількість повідомлень у розділі теми:
Також ви можете спробувати використовувати кафкакат . Це проект з відкритим кодом, який може допомогти вам прочитати повідомлення з теми та розділу та роздрукувати їх у stdout. Ось зразок, який читає останні 10 повідомлень з sample-kafka-topic
теми, а потім виходить:
kafkacat -b localhost:9092 -t sample-kafka-topic -p 0 -o -10 -e
Використовуйте https://prestodb.io/docs/current/connector/kafka-tutorial.html
Супер SQL-механізм, наданий Facebook, який підключається до кількох джерел даних (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
Щоб отримати всі повідомлення, що зберігаються за темою, ви можете шукати споживача до початку та кінця потоку для кожного розділу та підсумувати результати
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());
Виконайте наступне (припустимо 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
так як цей варіант більше не доступний (або , по- видимому необхідний)
За допомогою 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
seekToEnd(..)
і seekToBeginning(..)
методами , які змінюють стан з consumer
.
У мене було таке саме запитання, і ось як я це роблю, від 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()
Дуже грубий код, оскільки я щойно змусив це працювати, але в основному ви хочете відняти зміщення початку теми від кінцевого зміщення, і це буде поточний рахунок повідомлень для теми.
Ви не можете просто покладатися на кінцевий зсув через інші конфігурації (політика очищення, утримування-ms тощо), які можуть призвести до видалення старих повідомлень із вашої теми. Зміщення лише "рухаються" вперед, тому саме початковий зсув рухатиметься вперед ближче до кінця зсуву (або врешті-решт до того самого значення, якщо тема зараз не містить повідомлення).
В основному кінцевий зсув представляє загальну кількість повідомлень, які пройшли через цю тему, а різниця між ними представляє кількість повідомлень, які тема містить зараз.
Витяги з документів Kafka
Зниження в 0.9.0.0
Kafka-consumer-offset-checker.sh (kafka.tools.ConsumerOffsetChecker) застарілий. В майбутньому використовуйте kafka-consumer-groups.sh (kafka.admin.ConsumerGroupCommand) для цієї функції.
Я запускаю брокера Kafka з увімкненим 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
). Майте на увазі, що вам потрібно перевірити кожну з копій даного розділу, або вам потрібно з’ясувати, хто з посередників є лідером для даного розділу (і це може змінюватися з часом).
Крім того, ви можете використовувати споживчі методи KafkabeginningOffsets
та endOffsets
.
Найпростіший спосіб, який я знайшов, - це використовувати Kafdrop REST API /topic/topicName
і вказати заголовок key: "Accept"
/ value:, "application/json"
щоб повернути відповідь JSON.
Ви можете використовувати kafkatool . Будь ласка, перевірте це посилання -> http://www.kafkatool.com/download.html
Kafka Tool - це графічний додаток для управління та використання кластерів Apache Kafka. Він забезпечує інтуїтивно зрозумілий інтерфейс, який дозволяє швидко переглядати об'єкти в кластері Kafka, а також повідомлення, що зберігаються в темах кластера.