Java, วิธีรับจำนวนข้อความในหัวข้อใน apache kafka


93

ฉันใช้ apache kafka ในการส่งข้อความ ฉันได้ใช้งานผู้ผลิตและผู้บริโภคใน Java เราจะรับจำนวนข้อความในหัวข้อได้อย่างไร?

คำตอบ:


34

วิธีเดียวที่ควรคำนึงถึงสิ่งนี้จากมุมมองของผู้บริโภคคือการบริโภคข้อความและนับจากนั้น

โบรกเกอร์ Kafka เปิดเผยตัวนับ JMX สำหรับจำนวนข้อความที่ได้รับตั้งแต่เริ่มต้น แต่คุณไม่สามารถทราบได้ว่ามีการกำจัดไปแล้วกี่ข้อความ

ในสถานการณ์ที่พบบ่อยที่สุดข้อความใน Kafka จะถูกมองว่าเป็นสตรีมที่ไม่มีที่สิ้นสุดและการได้รับค่าที่ไม่ต่อเนื่องของจำนวนที่ถูกเก็บไว้ในดิสก์นั้นไม่เกี่ยวข้อง นอกจากนี้สิ่งต่างๆจะซับซ้อนมากขึ้นเมื่อจัดการกับกลุ่มโบรกเกอร์ซึ่งทั้งหมดมีส่วนย่อยของข้อความในหัวข้อ


ดูคำตอบของฉันstackoverflow.com/a/47313863/2017567 ไคลเอ็นต์ Java Kafka อนุญาตให้รับข้อมูลนั้น
Christophe Quintard

97

ไม่ใช่ 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 แล้วความแตกต่างส่งคืนข้อความที่รอดำเนินการจริงในหัวข้อ? ฉันถูกไหม?
kisna

1
ใช่นั่นเป็นความจริง คุณต้องคำนวณความแตกต่างหากการชดเชยที่เร็วที่สุดไม่เท่ากับศูนย์
ssemichev

นั่นคือสิ่งที่ฉันคิดว่า :).
kisna

1
มีวิธีใดบ้างที่จะใช้เป็น API และภายในโค้ด (JAVA, Scala หรือ Python)
กอบกู้

นี่คือการผสมผสานระหว่างรหัสของฉันและรหัสจาก Kafka มันอาจมีประโยชน์ ฉันใช้มันสำหรับสตรีมมิ่ง Spark - การรวม Kafka KafkaClient gist.github.com/ssemichev/c2d94dce7ad65339c9637e1b461f86cf KafkaCluster gist.github.com/ssemichev/fa3605c7b10cb6c7b9c8ab54ffbc5865
ssemichev

18

ฉันใช้สิ่งนี้เพื่อเปรียบเทียบ POC ของฉันจริงๆ รายการที่คุณต้องการใช้ ConsumerOffsetChecker คุณสามารถเรียกใช้โดยใช้ bash script ด้านล่าง

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

บางครั้งความสนใจอยู่ที่การรู้จำนวนข้อความในแต่ละพาร์ติชันตัวอย่างเช่นเมื่อทดสอบพาร์ติชันที่กำหนดเองขั้นตอนต่อมาได้รับการทดสอบเพื่อทำงานกับ Kafka 0.10.2.1-2 จาก Confluent 3.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 นี่คือตัวอย่างที่อ่าน 10 ข้อความสุดท้ายจากsample-kafka-topicหัวข้อแล้วออก:

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

11

ใช้https://prestodb.io/docs/current/connector/kafka-tutorial.html

เครื่องมือ Super SQL ที่จัดหาโดย Facebook ซึ่งเชื่อมต่อกับแหล่งข้อมูลต่างๆ (Cassandra, Kafka, JMX, Redis ...

PrestoDB กำลังทำงานเป็นเซิร์ฟเวอร์ที่มีคนงานเสริม (มีโหมดสแตนด์อโลนโดยไม่มีคนงานเพิ่มเติม) จากนั้นคุณใช้ JAR ที่ปฏิบัติการได้ขนาดเล็ก (เรียกว่า presto CLI) เพื่อสร้างแบบสอบถาม

เมื่อคุณกำหนดค่าเซิร์ฟเวอร์ Presto ได้ดีแล้วคุณสามารถใช้ Traditionalnal 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

การใช้ไคลเอนต์ 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

ฉันชอบคุณตอบเมื่อเทียบกับคำตอบ @AutomatedMike ตั้งแต่คำตอบของคุณไม่ได้ยุ่งกับseekToEnd(..)และวิธีการที่เปลี่ยนสถานะของseekToBeginning(..) consumer
adaslaw

2

ในรุ่นล่าสุดของคาฟคาผู้จัดการมีคอลัมน์บรรดาศักดิ์สรุป Offsets

ป้อนคำอธิบายภาพที่นี่


2

ฉันมีคำถามเดียวกันนี้และนี่คือวิธีที่ฉันทำจาก KafkaConsumer ใน Kotlin:

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

โค้ดหยาบมากเพราะฉันเพิ่งใช้งานได้ แต่โดยพื้นฐานแล้วคุณต้องการลบออฟเซ็ตเริ่มต้นของหัวข้อออกจากออฟเซ็ตสิ้นสุดและนี่จะเป็นจำนวนข้อความปัจจุบันสำหรับหัวข้อ

คุณไม่สามารถพึ่งพา end offset ได้เนื่องจากการกำหนดค่าอื่น ๆ (นโยบายการล้างข้อมูลการเก็บรักษา -ms ฯลฯ ) ที่อาจทำให้การลบข้อความเก่าออกจากหัวข้อของคุณ ออฟเซ็ตเฉพาะ "เดินหน้า" ไปข้างหน้าดังนั้นจึงเป็นการชดเชยที่เริ่มต้นซึ่งจะเลื่อนไปข้างหน้าใกล้กับค่าชดเชยสุดท้าย (หรือในที่สุดก็เป็นค่าเดียวกันหากหัวข้อไม่มีข้อความในตอนนี้)

โดยทั่วไปแล้วค่าชดเชยสุดท้ายจะแสดงจำนวนข้อความโดยรวมที่ผ่านหัวข้อนั้นและความแตกต่างระหว่างทั้งสองแสดงถึงจำนวนข้อความที่มีในหัวข้อนั้นในตอนนี้


0

ข้อความที่ตัดตอนมาจากเอกสาร 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

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 ConsumerbeginningOffsetsและendOffsets.




-1

คุณอาจจะใช้kafkatool โปรดตรวจสอบลิงค์นี้ -> http://www.kafkatool.com/download.html

Kafka Tool เป็นแอปพลิเคชั่น GUI สำหรับจัดการและใช้คลัสเตอร์ Apache Kafka มี UI ที่ใช้งานง่ายซึ่งช่วยให้สามารถดูวัตถุภายในคลัสเตอร์ Kafka ได้อย่างรวดเร็วรวมทั้งข้อความที่เก็บไว้ในหัวข้อของคลัสเตอร์ป้อนคำอธิบายภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.