2016-03-15 33 views
7

जब मैंने अपने संबंधित स्कीमा के साथ डेटा पर Kafka Consumer with Avro चलाने का प्रयास किया, तो यह "AvroRuntimeException: विकृत डेटा। लंबाई ऋणात्मक है: -40" की त्रुटि देता है। मुझे लगता है कि दूसरों के पास समान समस्याएं हैं coverting byte array to json, Avro write and read, और Kafka Avro Binary *coder। मैं भी इस Consumer Group Example है, जो सभी सहायक रहे संदर्भित किया है, फिर भी इस त्रुटि के साथ कोई मदद नहीं अब तक .. यह कोड (लाइन 73)डिकोडर मुद्दों के साथ काफ्का एवरो उपभोक्ता

डिकोडर विकोडक के इस हिस्से तक काम करता है = DecoderFactory.get()। BinaryDecoder (byteArrayInputStream, शून्य);

मैंने अन्य डिकोडर्स की कोशिश की है और बाइटएरेइन इनपुटस्ट्रीम वैरिएबल की सामग्री को मुद्रित किया है, जो दिखता है कि मुझे लगता है कि आप क्या मानते हैं कि आप धारावाहिक एरो डेटा देखने की उम्मीद करेंगे (संदेश में मैं स्कीमा और कुछ डेटा और कुछ विकृत डेटा देख सकता हूं) मेरे पास है .available() विधि का उपयोग करके उपलब्ध बाइट्स मुद्रित, जो 594 लौटाता है। मुझे यह समझने में परेशानी हो रही है कि यह त्रुटि क्यों हो रही है। अपाचे निफ़ी का उपयोग एचडीएफएस से उसी स्कीमा के साथ काफ्का स्ट्रीम का उत्पादन करने के लिए किया जाता है। किसी भी सहायता के लिए धन्यवाद।

उत्तर

13

शायद समस्या यह है कि निफ्टी बनाम एवरो डेटा कैसे लिखा जाता है (एनकोडेड) कैसे होता है। आपका उपभोक्ता ऐप डेटा को कैसे पढ़ रहा है (डीकोडिंग)।

  1. उचित एवरो फ़ाइलों बनाने के लिए:: डेटा रिकॉर्ड सांकेतिक शब्दों में बदलना करने के लिए, लेकिन यह भी प्रस्तावना की एक किस्म में एवरो स्कीमा एम्बेड करने के लिए (के माध्यम से

    संक्षेप में, एवरो के एपीआई क्रमबद्धता के लिए दो अलग-अलग दृष्टिकोण प्रदान करता है org.apache.avro.file.{DataFileWriter/DataFileReader})। एवरो फाइलों में स्कीमा को एम्बेड करना बहुत समझ में आता है क्योंकि (ए) आम तौर पर एवरो फाइलों का "पेलोड" एम्बेडेड एवरो स्कीमा से बड़ा परिमाण का ऑर्डर होता है और (बी) फिर आप उन फ़ाइलों को प्रतिलिपि बना सकते हैं या अपने दिल की सामग्री पर ले जा सकते हैं और फिर भी सुनिश्चित करें कि आप किसी को या किसी से परामर्श किए बिना उन्हें फिर से पढ़ सकते हैं।

  2. केवल डेटा रिकॉर्ड एन्कोड करने के लिए, यानी स्कीमा को एम्बेड न करने के लिए (org.apache.avro.io.{BinaryEncoder/BinaryDecoder} के माध्यम से; पैकेज नाम में अंतर नोट करें: io ऊपर बनाम file बनाम)। इस दृष्टिकोण को अक्सर पसंद किया जाता है जब एवरो-एन्कोडिंग संदेश जो कफका विषय पर लिखे जा रहे हैं, उदाहरण के लिए, क्योंकि आपके ऊपर संस्करण 1 की तुलना में एवरो स्कीमा को प्रत्येक संदेश में फिर से एम्बेड करने के ऊपरी हिस्से को नहीं लेते हैं, यह मानते हुए कि आपका (बहुत ही उचित) नीति यह है कि, उसी कफका विषय के लिए, संदेशों को उसी एवरो स्कीमा के साथ स्वरूपित/एन्कोड किया जाता है। यह एक महत्वपूर्ण लाभ है क्योंकि, स्ट्रीम डेटा संदर्भ में, डेटा-इन-मोशन डेटा रिकॉर्ड आम तौर पर वर्णित डेटा-एट-रेस्ट एवरो फ़ाइलों की तुलना में आमतौर पर बहुत छोटा होता है (आमतौर पर 100 बाइट्स और कुछ सौ केबी के बीच) (अक्सर सैकड़ों या हजारों एमबी); इसलिए एवरो स्कीमा का आकार अपेक्षाकृत बड़ा है, और इस प्रकार आप काफ़का को 2000 डेटा रिकॉर्ड लिखते समय इसे 2000x एम्बेड करना नहीं चाहते हैं। दोष यह है कि आपको "किसी भी तरह" ट्रैक करना चाहिए कि कैसे एवरो स्कीमा कैफका विषयों को मानचित्रित करते हैं - या अधिक सटीक रूप से, आपको किसी भी तरह से ट्रैक करना होगा कि एवरो स्कीमा को स्कीमा को सीधे एम्बेड करने के रास्ते को बिना किसी एन्कोड किया गया था। अच्छी खबर यह है कि यह पारदर्शी रूप से करने के लिए tooling available in the Kafka ecosystem (Avro schema registry) है। तो संस्करण 1 की तुलना में, सुविधा के खर्च पर दक्षता पर 2 लाभ भिन्न हैं।

प्रभाव यह है कि एन्कोडेड एवरो डेटा के लिए "तार प्रारूप" इस पर निर्भर करता है कि आप ऊपर (1) या (2) का उपयोग करते हैं या नहीं।

मैं अपाचे निफ़ी से बहुत परिचित नहीं हूं, लेकिन स्रोत कोड (उदा। ConvertAvroToJSON.java) पर एक त्वरित रूप से मुझे पता चलता है कि यह संस्करण 1 का उपयोग कर रहा है, यानी यह एवरो रिकॉर्ड के साथ एवरो स्कीमा को एम्बेड करता है। आपका उपभोक्ता कोड, हालांकि, DecoderFactory.get().binaryDecoder() का उपयोग करता है और इस प्रकार संस्करण 2 (कोई स्कीमा एम्बेडेड नहीं)।

शायद यह उस त्रुटि को बताता है जिसमें आप चल रहे हैं?

+1

धन्यवाद @ miguno यह बिल्कुल था! मैं डेटाफ़ाइल रीडर को दो लाइन परिवर्तनों के साथ डीकोडर का उपयोग करके रॉकिंग और रोलिंग कर रहा हूं। DatumReader डेटामडर = नया विशिष्ट डेटामडर <जेनेरिक रिकॉर्डर> (स्कीमा); डेटाफाइलस्ट्रीम <जेनेरिक रेकॉर्ड> डेटाफाइल रीडर = नया डेटाफाइलस्ट्रीम <जेनेरिक रिकॉर्डर> (इनपुटस्ट्रीम, डाटाम रीडर); – SparkleGoat

+0

सुधार * मैं अब रॉकिंग और रोलिंग कर रहा हूं कि मैं डेटाफाइल रीडर में दो पंक्ति परिवर्तनों के साथ बदल गया। आप सही बाइनरी हैं डिकोडर नौकरी के लिए सही विकल्प नहीं था। – SparkleGoat

+1

खुशी हुई यह काम किया! –

संबंधित मुद्दे