簡體   English   中英

帶解碼器問題的Kafka Avro Consumer

[英]Kafka Avro Consumer with Decoder issues

當我嘗試使用我的相應模式使用Avro運行Kafka Consumer時 ,它返回錯誤“AvroRuntimeException:格式錯誤的數據。長度為負:-40”。 我看到其他人有類似的問題將字節數組轉換為jsonAvro寫入和讀取 ,以及Kafka Avro Binary *編碼器 我也引用了這個消費者組示例 ,它們都很有幫助,但到目前為止這個錯誤沒有任何幫助..它可以工作到這部分代碼(第73行)

解碼器解碼器= DecoderFactory.get()。binaryDecoder(byteArrayInputStream,null);

我已經嘗試了其他解碼器並打印出byteArrayInputStream變量的內容,它看起來我相信你會期望序列化的avro數據看起來(在消息中我可以看到模式和一些數據以及一些格式錯誤的數據)我打印出來了使用.available()方法可用的字節,返回594.我無法理解為什么會發生此錯誤。 Apache Nifi用於生成具有來自hdfs的相同模式的Kafka流。 我將不勝感激任何幫助。

也許問題是Nifi如何編寫(編碼)Avro數據與消費者應用程序讀取(解碼)數據的方式不匹配。

簡而言之,Avro的API提供了兩種不同的序列化方法:

  1. 用於創建正確的Avro 文件 :對數據記錄進行編碼,還要將Avro架構嵌入到一種前導碼中(通過org.apache.avro.file.{DataFileWriter/DataFileReader} )。 將模式嵌入到Avro文件中非常有意義,因為(a)Avro文件的“有效負載”通常比嵌入式Avro模式大一些,並且(b)然后您可以根據自己的內容復制或移動這些文件並且仍然可以確保您可以再次閱讀它們,而無需咨詢某人或某事。
  2. 僅編碼數據記錄,即不嵌入模式(通過org.apache.avro.io.{BinaryEncoder/BinaryDecoder} ;請注意包名稱的差異: io here vs file above)。 例如,當Avro編碼正在寫入Kafka主題的消息時,這種方法通常很受歡迎,因為與上面的變體1相比,您不會產生將Avro架構重新嵌入到每個消息中的開銷,假設您的(非常合理)策略是,對於相同的Kafka主題,消息使用相同的Avro架構進行格式化/編碼。 這是一個顯着的優點,因為在流數據上下文中,動態數據記錄通常比如上所述的靜態數據Avro文件小得多(通常在100字節到幾百KB之間)(通常是數百或者數千MB); 所以Avro架構的大小相對較大,因此在將2000個數據記錄寫入Kafka時,您不希望將其嵌入2000x。 缺點是您必須“以某種方式”跟蹤Avro架構如何映射到Kafka主題 - 或者更准確地說,您必須以某種方式跟蹤編碼消息的Avro架構,而不必直接嵌入架構的路徑。 好消息是Kafka生態系統(Avro架構注冊表)中有工具可用於透明地執行此操作。 因此,與變體1相比,變體2以便利性為代價獲得了效率。

結果是,編碼的Avro數據的“有線格式”看起來會有所不同,具體取決於您使用上面的(1)還是(2)。

我對Apache Nifi不是很熟悉,但是快速查看源代碼(例如ConvertAvroToJSON.java )向我建議它使用變量1,即它將Avro架構與Avro記錄一起嵌入。 但是,您的使用者代碼使用DecoderFactory.get().binaryDecoder() ,因此使用變體2(沒有嵌入模式)。

也許這解釋了你遇到的錯誤?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM