जावा, अपाचे काफ्का में एक विषय में संदेशों की संख्या कैसे प्राप्त करें


93

मैं मैसेजिंग के लिए अपाचे काफ्का का उपयोग कर रहा हूं। मैंने निर्माता और उपभोक्ता को जावा में लागू किया है। हम किसी विषय में संदेशों की संख्या कैसे प्राप्त कर सकते हैं?

जवाबों:


34

एक उपभोक्ता दृष्टिकोण से इसके लिए दिमाग में आने वाला एकमात्र तरीका वास्तव में संदेशों का उपभोग करना और फिर उन्हें गिनना है।

काफ्का दलाल स्टार्ट-अप के बाद से प्राप्त संदेशों की संख्या के लिए जेएमएक्स काउंटरों को उजागर करता है, लेकिन आप यह नहीं जान सकते कि उनमें से कितने को पहले ही शुद्ध किया जा चुका है।

सबसे आम परिदृश्यों में, काफ्का के संदेशों को एक अनंत धारा के रूप में देखा जाता है और डिस्क पर वर्तमान में रखे जाने वाले कितने का एक असतत मूल्य प्राप्त करना प्रासंगिक नहीं है। दलालों के एक समूह के साथ काम करते समय इसके अलावा चीजें और अधिक जटिल हो जाती हैं जो सभी एक विषय में संदेशों का एक सबसेट है।


मेरा उत्तर देखें stackoverflow.com/a/47313863/2017567 । जावा कफ़्का ग्राहक उस जानकारी को प्राप्त करने की अनुमति देता है।
क्रिस्टोफ क्विंटार्ड

96

यह जावा नहीं है, लेकिन उपयोगी हो सकता है

./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 और फिर अंतर विषय में वास्तविक लंबित संदेशों को लौटाता है? क्या मैं सही हूँ?
किशन

1
हाँ यह सच है। आपको एक अंतर की गणना करनी होगी यदि प्रारंभिक ऑफसेट शून्य के बराबर नहीं है।
17

बिल्कुल यही मैने सोचा :)।
किस्ना

1
वहाँ एक एपीआई के रूप में उपयोग करने के लिए कोई रास्ता नहीं है और इसलिए एक कोड के अंदर (जावा, स्काला या पायथन)?
साल्वो

यहाँ काफ्का से मेरे कोड और कोड का मिश्रण है। यह उपयोगी हो सकता है। काफ्का एकीकरण KafkaClient - मैं स्पार्क स्ट्रीमिंग के लिए यह प्रयोग किया जाता gist.github.com/ssemichev/c2d94dce7ad65339c9637e1b461f86cf KafkaCluster gist.github.com/ssemichev/fa3605c7b10cb6c7b9c8ab54ffbc5865
ssemichev

16

मैं वास्तव में इसका उपयोग अपने POC बेंचमार्किंग के लिए करता हूं। वह आइटम जो आप ConsumerOffsetChecker का उपयोग करना चाहते हैं। आप इसे नीचे की तरह बैश स्क्रिप्ट का उपयोग करके चला सकते हैं।

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 $)
ज़ीमॉन Sadło

1
हाँ, यही मैंने कहा है।
रूडी

आपका अंतिम वाक्य सटीक नहीं है। उपरोक्त कमांड अभी भी 0.10.0.1 में काम करता है और चेतावनी मेरी पिछली टिप्पणी के समान है।
सिजमन सैडलो

14

कभी-कभी रुचि प्रत्येक विभाजन में संदेशों की संख्या जानने में होती है, उदाहरण के लिए, जब एक कस्टम पार्टीशनर का परीक्षण किया जाता है। आगामी चरणों को कंफ्लुएंट 3.2 से काफ्का 0.10.2.1-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

विषय के लिए विभाजन की संख्या के आधार पर लाइनों की संख्या कम या ज्यादा हो सकती है।


4
यदि लॉग संघनन सक्षम है, तो विभाजन के ऑफसेट को विषय में संदेशों की सटीक गणना नहीं दे सकता है।

14

चूंकि ConsumerOffsetCheckerअब समर्थित नहीं है, आप इस कमांड का उपयोग विषय के सभी संदेशों को जांचने के लिए कर सकते हैं:

bin/kafka-run-class.sh kafka.admin.ConsumerGroupCommand \
    --group my-group \
    --bootstrap-server localhost:9092 \
    --describe

LAGविषय विभाजन में संदेशों की गिनती कहाँ है:

यहाँ छवि विवरण दर्ज करें

इसके अलावा आप काफ्काट का उपयोग करने की कोशिश कर सकते हैं । यह एक ओपन सोर्स प्रोजेक्ट है जो आपको किसी विषय और विभाजन से संदेश पढ़ने में मदद कर सकता है और उन्हें स्टडआउट करने के लिए प्रिंट करता है। यहां एक नमूना है जो sample-kafka-topicविषय से अंतिम 10 संदेशों को पढ़ता है , फिर बाहर निकलें:

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

11

Https://prestodb.io/docs/current/connector/kafka-tutorial.html का उपयोग करें

फेसबुक द्वारा प्रदान किया गया एक सुपर एसक्यूएल इंजन, जो कई डेटा स्रोतों (कैसंड्रा, काफ्का, जेएमएक्स, रेडिस ...) से जुड़ता है।

PrestoDB वैकल्पिक श्रमिकों के साथ एक सर्वर के रूप में चल रहा है (अतिरिक्त श्रमिकों के बिना एक स्टैंडअलोन मोड है), फिर आप प्रश्नों को बनाने के लिए एक छोटे निष्पादन योग्य JAR (जिसे Presto CLI कहा जाता है) का उपयोग करते हैं।

एक बार जब आप प्रेस्टो सर्वर को अच्छी तरह से कॉन्फ़िगर कर लेते हैं, तो आप ट्रेडिशनल एसक्यूएल का उपयोग कर सकते हैं:

SELECT count(*) FROM TOPIC_NAME;

यह उपकरण अच्छा है, लेकिन अगर यह आपके काम के 2 डॉट्स से अधिक का नहीं है।
आयुध

7

अपाचे काफ्का कमांड को किसी विषय के सभी विभाजनों पर संयुक्त रूप से नियंत्रित संदेश प्राप्त करने के लिए:

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क्योंकि वह विकल्प अब उपलब्ध नहीं है (या जाहिरा तौर पर आवश्यक)
स्टीफनबॉश

3

कफ़्का 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

काफ्का प्रबंधक के अधिकांश हाल के संस्करणों में, एक कॉलम है जिसका शीर्षक है सुम्मी हाल के ऑफ़सेट्स

यहाँ छवि विवरण दर्ज करें


2

मेरा भी यही सवाल था और यह मैं इसे कफल्कंसुमेर के कोटलिन में कैसे कर रहा हूं:

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

बहुत कठिन कोड, जैसा कि मुझे अभी यह काम करने के लिए मिला है, लेकिन मूल रूप से आप विषय की शुरुआत ऑफसेट को समाप्ति ऑफसेट से घटाना चाहते हैं और यह विषय के लिए वर्तमान संदेश गणना होगी।

आप अन्य कॉन्फ़िगरेशन (क्लीनअप पॉलिसी, रिटेंशन-एमएस, आदि) की वजह से अंतिम ऑफसेट पर भरोसा नहीं कर सकते हैं जो आपके विषय से पुराने संदेशों को हटाने का कारण बन सकते हैं। ऑफसेट केवल "आगे" आगे बढ़ते हैं, इसलिए यह भिखारी ऑफसेट है जो अंत ऑफसेट के करीब आगे बढ़ेगा (या अंततः उसी मूल्य पर, यदि विषय में अभी कोई संदेश नहीं है)।

मूल रूप से अंत ऑफ़सेट उस विषय के माध्यम से गए संदेशों की कुल संख्या का प्रतिनिधित्व करता है, और दोनों के बीच का अंतर उन संदेशों की संख्या का प्रतिनिधित्व करता है जिनमें विषय अभी शामिल है।


0

काफ्का डॉक्स के कुछ अंश

0.9.0.0 में पदावनति

Kafka-consumer-offset-checker.sh (kafka.tools.ConsumerOffsetChecker) को हटा दिया गया है। आगे बढ़ते हुए, कृपया इस कार्यक्षमता के लिए kafka-consumer-groups.sh (kafka.admin.ConsumerGroupCommand) का उपयोग करें।

मैं सर्वर और क्लाइंट दोनों के लिए एसएसएल सक्षम के साथ काफ्का दलाल चला रहा हूं। नीचे आदेश मैं का उपयोग करें

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)। ध्यान रखें कि आपको दिए गए विभाजन के प्रत्येक प्रतिक के लिए जाँच करने की आवश्यकता है, या आपको यह पता लगाने की आवश्यकता है कि दलालों में से कौन सा किसी दिए गए विभाजन के लिए नेता है (और यह समय के साथ बदल सकता है)।

वैकल्पिक रूप से, आप काफ्का उपभोक्ता विधियों का उपयोग कर सकते हैं beginningOffsetsऔर endOffsets


-1

मैंने खुद यह कोशिश नहीं की है, लेकिन यह समझ में आता है।

आप kafka.tools.ConsumerOffsetChecker( स्रोत ) का उपयोग भी कर सकते हैं ।


-1

मैंने जो सबसे आसान तरीका पाया है, वह है Kafdrop REST API का उपयोग करना /topic/topicNameऔर कुंजी को निर्दिष्ट करना: "Accept"/ मान: "application/json"हैडर एक JSON प्रतिक्रिया प्राप्त करने के लिए।

यह यहाँ प्रलेखित है


-1

आप काफकटूल का उपयोग कर सकते हैं । कृपया इस लिंक को देखें -> http://www.kafkatool.com/download.html

काफ्का उपकरण अपाचे काफ्का समूहों के प्रबंधन और उपयोग के लिए एक जीयूआई अनुप्रयोग है। यह एक सहज ज्ञान युक्त यूआई प्रदान करता है जो किसी को काफ्का क्लस्टर के साथ-साथ क्लस्टर के विषयों में संग्रहीत संदेशों को देखने की अनुमति देता है।यहाँ छवि विवरण दर्ज करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.