簡體   English   中英

為什么將Avro與Kafka一起使用 - 如何處理POJO

[英]Why use Avro with Kafka - How to handle POJOs

我有一個春季應用程序,是我的kafka制作人,我想知道為什么avro是最好的方式去。 我讀到了它以及它所提供的一切,但為什么我不能將我自己用傑克遜創建的POJO序列化並將其發送給kafka?

我這樣說是因為avro的POJO代並不是那么直截了當。 最重要的是,它需要maven插件和.avsc文件。

所以例如我在我的kafka制作人上創建了一個名為User的POJO:

public class User {

    private long    userId;

    private String  name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }

}

我將其序列化並將其發送到我在kafka中的用戶主題。 然后我有一個消費者,它本身有一個POJO用戶並反序列化該消息。 這是空間問題嗎? 以這種方式序列化和反序列化也不是更快嗎? 更不用說維護模式注冊表有一個開銷。

這是速度和存儲的問題。 在序列化數據時,您經常需要傳輸實際模式,因此會導致有效負載大小的增加。

                            Total Payload Size
+-----------------+--------------------------------------------------+
|     Schema      |                 Serialised Data                  |
+-----------------+--------------------------------------------------+

Schema Registry為模式和元數據提供集中存儲庫,以便所有模式都在中央系統中注冊。 這個集中式系統使生產者只能包含模式的ID而不是完整模式本身(文本格式)。

                      Total Payload Size
+----+--------------------------------------------------+
| ID |                 Serialised Data                  |
+----+--------------------------------------------------+

因此,序列化變得更快。

此外,架構注冊表版本控制可以實施數據策略,這些策略可能有助於防止較新的架構破壞與現有版本的兼容性,這些版本可能會導致停機或管道中的任何其他重大問題。


Confluent本文中詳細解釋了Schema Registry的一些其他好處。

你不需要AVSC, 你可以使用AVDL文件 ,它基本上看起來像只有字段的POJO

@namespace("com.example.mycode.avro")
protocol ExampleProtocol {
   record User {
     long id;
     string name;
   }
}

當使用Maven插件的idl-protocol目標時,將為您創建此AVSC,而不是您自己編寫它。

{
  "type" : "record",
  "name" : "User",
  "namespace" : "com.example.mycode.avro",
  "fields" : [ {
    "name" : "id",
    "type" : "long"
  }, {
    "name" : "name",
    "type" : "string"
  } ]
}

它還會在您的類路徑中放置一個SpecificData POJO User.java ,以便在您的代碼中使用。


如果您已經有POJO,則無需使用AVSC或AVDL文件。 有轉換POJO的庫。 例如,你可以使用 Jackson ,它不僅僅是JSON,你只需要為Kafka創建一個JacksonAvroSerializer ,或者查找是否存在。

Avro還具有基於反射的內置庫


那么問題 - 為什么Avro(對於Kafka)?

好吧,擁有一個架構是一件好事 想想RDBMS表,你可以解釋一下表,然后你會看到所有的列。 轉移到NoSQL文檔數據庫,它們可以包含任何內容,這就是Kafka的JSON世界。

假設您的Kafka群集中的消費者不知道主題中的內容,他們必須確切地知道主題中產生了誰/什么。 他們可以嘗試控制台消費者,如果它是像JSON這樣的明文,那么他們必須弄清楚他們感興趣的一些字段,然后一次又一次地執行類似HashMap的.get("name")操作,只運行當一個字段不存在時進入NPE。 使用Avro,您可以清楚地定義默認值和可空字段。

不需要使用模式注冊表,但它為RDBMS類比提供了這種類型的explain topic語義。 它還使您無需發送架構以及每條消息,以及Kafka主題上額外帶寬的費用。 注冊表不僅對Kafka有用,因為它可以用於Spark,Flink,Hive等所有圍繞流數據攝取的數據科學分析。


假設您確實想要使用JSON,那么請嘗試使用MsgPack ,您可能會看到Kafka吞吐量增加並節省了代理上的磁盤空間


你可以使用其他格式,如Protobuf或Thrift, 正如Uber所做的那樣

首先 - 卡夫卡不知道關鍵/價值內容。 它操作字節,它的客戶端(生產者/消費者)負責照顧de / serialization。

到目前為止,最常見的選項似乎是JSON,protobuf和Avro。

我個人喜歡Avro以及為什么我經常使用它並推薦給其他人:

1)這是一個足夠緊湊的二進制序列化,具有模式和邏輯類型 (有助於區分timestamp in long millis的常規longtimestamp in long millis

2)Avro模式非常具有描述性並且完整記錄

3)大多數廣泛使用的編程語言都是必須的!

4)Confluent(和其他)為模式提供存儲庫,即所謂的“模式注冊表”,以便為模式提供集中存儲。 在Avro中,消息僅包含架構版本ID,而不包含架構本身。

5)如果您使用的是Java,那么使用模式中的POJO基類生成可以獲得很大的好處。

當然,您可以將其中的一部分與其他選項一起使用。 您應該嘗試比較適合您的用例的所有選項。

PS我非常個人的建議是:如果不是String ,請選擇Avro。 適用於鍵和值。

暫無
暫無

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

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