メッセージングにApachekafkaを使用しています。私は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の使用を開始することをお勧めします。
カスタムパーティショナーをテストする場合など、各パーティション内のメッセージの数を知ることに関心がある場合があります。次の手順は、Confluent3.2のKafka0.10.2.1-2で動作するようにテストされています。Kafkaトピック、kt
および次のコマンドラインがあるとします。
$ kafka-run-class kafka.tools.GetOffsetShell \
--broker-list host01:9092,host02:9092,host02:9092 --topic kt
これにより、3つのパーティション内のメッセージの数を示すサンプル出力が出力されます。
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
トピックパーティション内のメッセージの数はどこにありますか。
また、kafkacatを使用してみることができます。これは、トピックとパーティションからメッセージを読み取り、それらをstdoutに出力するのに役立つオープンソースプロジェクトです。sample-kafka-topic
トピックから最後の10個のメッセージを読み取り、終了するサンプルを次に示します。
kafkacat -b localhost:9092 -t sample-kafka-topic -p 0 -o -10 -e
https://prestodb.io/docs/current/connector/kafka-tutorial.htmlを使用します
Facebookが提供する、複数のデータソース(Cassandra、Kafka、JMX、Redisなど)に接続するスーパーSQLエンジン。
PrestoDBは、オプションのワーカーを備えたサーバーとして実行されており(追加のワーカーがないスタンドアロンモードがあります)、小さな実行可能JAR(presto CLIと呼ばれます)を使用してクエリを実行します。
Prestoサーバーを適切に構成したら、従来のSQLを使用できます。
SELECT count(*) FROM TOPIC_NAME;
トピックのすべてのパーティションで未処理のメッセージを取得するApacheKafkaコマンド:
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
、そのオプションが利用できなくなっ(または明らかに必要)があるため
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
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()
これが機能するようになったので、非常に大まかなコードですが、基本的には、トピックの開始オフセットを終了オフセットから減算すると、これがトピックの現在のメッセージ数になります。
トピックから古いメッセージが削除される可能性のある他の構成(クリーンアップポリシー、retention-msなど)があるため、エンドオフセットだけに依存することはできません。オフセットは前方に「移動」するだけなので、終了オフセットに近づく(またはトピックに現在メッセージが含まれていない場合は最終的に同じ値に移動する)のは最初のオフセットです。
基本的に、終了オフセットは、そのトピックを通過したメッセージの総数を表し、2つの違いは、トピックに現在含まれているメッセージの数を表します。
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
(TOPICNAME
&を置き換える必要がありますPARTITIONNUMBER
)。クマは念頭に置いて、あなたは、特定のパーティションのレプリカごとにチェックする必要がある、またはあなたがのためのリーダーであるブローカーのどちらを知る必要がある特定のパーティション(これは、時間とともに変化することができます)。
または、KafkaConsumerメソッドbeginningOffsets
とを使用することもできますendOffsets
。
私が見つけた最も簡単な方法は、Kafdrop REST APIを使用し、JSON応答を取得するために/topic/topicName
key:"Accept"
/ value:"application/json"
ヘッダーを指定することです。
kafkatoolを使用できます。このリンクを確認してください-> http://www.kafkatool.com/download.html
Kafka Toolは、ApacheKafkaクラスターを管理および使用するためのGUIアプリケーションです。これは、Kafkaクラスター内のオブジェクトとクラスターのトピックに保存されているメッセージをすばやく表示できる直感的なUIを提供します。