Mesajlaşma için apache kafka kullanıyorum. Üreticiyi ve tüketiciyi Java'da uyguladım. Bir konudaki mesaj sayısını nasıl alabiliriz?
Yanıtlar:
Tüketici açısından bunun için akla gelen tek yol, mesajları gerçekten tüketip o zaman saymaktır.
Kafka komisyoncusu, başlangıçtan bu yana alınan mesaj sayısı için JMX sayaçlarını ortaya çıkarır, ancak bunlardan kaç tanesinin zaten temizlendiğini bilemezsiniz.
En yaygın senaryolarda, Kafka'daki mesajlar en iyi şekilde sonsuz bir akış olarak görülür ve şu anda diskte kaç tane tutulduğuna dair ayrı bir değer almak alakalı değildir. Dahası, hepsi bir konudaki mesajların bir alt kümesine sahip olan bir broker kümesi ile uğraşırken işler daha karmaşık hale gelir.
Java değil ama faydalı olabilir
./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
Ve sonra fark, konudaki gerçek bekleyen mesajları döndürür? Doğrumuyum?
Aslında bunu POC'umu karşılaştırmak için kullanıyorum. ConsumerOffsetChecker'ı kullanmak istediğiniz öğe. Aşağıdaki gibi bash betiğini kullanarak çalıştırabilirsiniz.
bin/kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --topic test --zookeeper localhost:2181 --group testgroup
Sonuç aşağıdadır: Kırmızı kutuda görebileceğiniz gibi 999, şu anda konudaki mesaj sayısıdır.
Güncelleme: ConsumerOffsetChecker, 0.10.0'dan beri kullanımdan kaldırılmıştır, ConsumerGroupCommand'ı kullanmaya başlamak isteyebilirsiniz.
Bazen ilgi, örneğin özel bir bölümleyiciyi test ederken her bölümdeki mesaj sayısını bilmektir. Sonraki adımlar Confluent 3.2'den Kafka 0.10.2.1-2 ile çalışmak üzere test edilmiştir. Bir Kafka konusu kt
ve aşağıdaki komut satırı verildiğinde :
$ kafka-run-class kafka.tools.GetOffsetShell \
--broker-list host01:9092,host02:9092,host02:9092 --topic kt
Bu, üç bölümdeki mesajların sayısını gösteren örnek çıktıyı yazdırır:
kt:2:6138
kt:1:6123
kt:0:6137
Konu için bölüm sayısına bağlı olarak satır sayısı az ya da çok olabilir.
Yana ConsumerOffsetChecker
artık desteklenmiyor, konuya tüm iletileri kontrol etmek için bu komutu kullanabilirsiniz:
bin/kafka-run-class.sh kafka.admin.ConsumerGroupCommand \
--group my-group \
--bootstrap-server localhost:9092 \
--describe
LAG
Konu bölümündeki mesajların sayısı nerede :
Ayrıca kafkacat kullanmayı deneyebilirsiniz . Bu, bir konu ve bölümdeki mesajları okumanıza yardımcı olabilecek ve bunları standart çıktıya yazdıran açık kaynaklı bir projedir. Konudaki son 10 mesajı okuyan ve sample-kafka-topic
ardından çıkılan bir örnek :
kafkacat -b localhost:9092 -t sample-kafka-topic -p 0 -o -10 -e
Https://prestodb.io/docs/current/connector/kafka-tutorial.html kullanın
Facebook tarafından sağlanan ve çeşitli veri kaynaklarına (Cassandra, Kafka, JMX, Redis ...) bağlanan süper bir SQL motoru.
PrestoDB, isteğe bağlı çalışanların bulunduğu bir sunucu olarak çalışıyor (fazladan çalışanların olmadığı bağımsız bir mod var), ardından sorgu yapmak için küçük bir yürütülebilir JAR (presto CLI olarak adlandırılıyor) kullanıyorsunuz.
Presto sunucusunu iyi yapılandırdıktan sonra, geleneksel SQL'i kullanabilirsiniz:
SELECT count(*) FROM TOPIC_NAME;
Apache Kafka bir konunun tüm bölümlerinde işlenmemiş mesajları almak için komut:
kafka-run-class kafka.tools.ConsumerOffsetChecker
--topic test --zookeeper localhost:2181
--group test_group
Baskılar:
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
Sütun 6, işlenmemiş mesajlardır. Bunları şu şekilde ekleyin:
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 satırları okur, başlık satırını atlar ve 6. sütunu toplar ve sonunda toplamı yazdırır.
Baskılar
5
Konu için depolanan tüm mesajları almak için, tüketiciyi her bölüm için akışın başına ve sonuna kadar arayabilir ve sonuçları toplayabilirsiniz.
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());
Aşağıdakini çalıştırın ( kafka-console-consumer.sh
yolda olduğunu varsayarak ):
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
o seçenek artık mevcut (ya da görünüşte gerekli) olduğu için
Kafka 2.11-1.0.0'ın Java istemcisini kullanarak aşağıdakileri yapabilirsiniz:
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));
}
}
}
Çıktı şuna benzer:
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(..)
ve seekToBeginning(..)
durumunu değiştirmek yöntemleri consumer
.
Aynı soruyu sormuştum ve Kotlin'de bir KafkaConsumer'den bunu nasıl yapıyorum:
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()
Çok kaba bir kod, bunu daha yeni çalıştırdım, ancak temelde konunun başlangıç ofsetini bitiş ofsetinden çıkarmak istiyorsunuz ve bu, konu için geçerli mesaj sayısı olacaktır.
Konunuzdan eski mesajların silinmesine neden olabilecek diğer yapılandırmalar (temizleme politikası, bekletme-ms vb.) Nedeniyle yalnızca bitiş ofsetine güvenemezsiniz. Ofsetler yalnızca ileriye doğru "hareket eder", bu nedenle bitiş ofsetine daha yakın ileriye doğru hareket edecek olan başlangıç ofsetidir (veya konu şu anda mesaj içermiyorsa, sonunda aynı değere).
Temel olarak bitiş uzaklığı, o konudan geçen toplam mesaj sayısını temsil eder ve ikisi arasındaki fark, konunun şu anda içerdiği mesajların sayısını temsil eder.
Kafka docs'dan alıntılar
0.9.0.0'daki kullanımdan kaldırmalar
Kafka-consumer-offset-checker.sh (kafka.tools.ConsumerOffsetChecker) kullanımdan kaldırıldı. İleriye dönük olarak, lütfen bu işlevsellik için kafka-consumer-groups.sh (kafka.admin.ConsumerGroupCommand) kullanın.
Kafka broker'ı hem sunucu hem de istemci için SSL etkinleştirilmiş olarak çalıştırıyorum. Kullandığım komutun altında
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 aşağıdaki gibidir
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
Sunucunun JMX arayüzüne erişiminiz varsa, başlangıç ve bitiş uzaklıkları şu konumlarda mevcuttur:
kafka.log:type=Log,name=LogStartOffset,topic=TOPICNAME,partition=PARTITIONNUMBER
kafka.log:type=Log,name=LogEndOffset,topic=TOPICNAME,partition=PARTITIONNUMBER
( TOPICNAME
& değiştirmelisiniz PARTITIONNUMBER
). Ayı akılda size verilen bölüm kopyaları her biri için kontrol etmeniz gerekir, yoksa broker biri lideri için hangi bulmak gerekiyor verilmiş bölüm (ve bu zaman içinde değişebilir).
Alternatif olarak, Kafka Tüketici yöntemlerini beginningOffsets
ve endOffsets
.
Bulduğum en basit yol, Kafdrop REST API'sini kullanmak ve bir JSON yanıtını geri almak /topic/topicName
için key: "Accept"
/ value: "application/json"
header'ı belirtmektir .
Kafkatool kullanabilirsiniz . Lütfen bu bağlantıyı kontrol edin -> http://www.kafkatool.com/download.html
Kafka Aracı, Apache Kafka kümelerini yönetmek ve kullanmak için bir GUI uygulamasıdır. Kişinin bir Kafka kümesindeki nesnelerin yanı sıra kümenin konularında depolanan mesajları hızlı bir şekilde görüntülemesini sağlayan sezgisel bir kullanıcı arabirimi sağlar.