Kafka使用Avro序列化data

       如果您正開始使用Kafka,那麼您需要做的一件事就是選擇一種數據格式。最重要的是在使用過程中保持一致。任何格式,無論是XML、JSON還是ASN.1,如果它在所有領域都得到一致的使用,那麼它總比一堆亂七八糟的臨時選擇要好。
       但如果你是從頭開始使用Kafka,哪一種格式最好?這裏有許多標準:效率、易用性、對不同編程語言的支持,等等。在我們自己的使用中,我們發現Apache Avro是流數據更好的選擇之一。
       Avro有一個類似JSON的數據模型,但可以表示爲JSON或緊湊的二進制形式。它提供了一種非常複雜的模式描述語言來描述數據。
       我們認爲Avro是最好的選擇,原因如下:
(1)它可以直接從json映射,或直接映射爲json格式。
(2)擁有非常緊湊的格式。
(3)非常快。
(4)它爲各種編程語言提供了強大的綁定,因此可以生成更容易處理事件數據的Java對象,但不需要生成代碼,因此可以爲任何數據流編寫通用的工具。
(5)它有一個用純JSON定義的豐富的、可擴展的模式語言。

       儘管處理這種元數據似乎是一件小事,但事實證明,在保持數據的高質量和易於在組織範圍內使用方面,處理這種元數據是最關鍵和最不受重視的方面之一。

       Avro的一個關鍵特性是能夠爲數據定義模式。例如,代表產品銷售的事件可能是這樣的:

{
  "time": 1424849130111,
  "customer_id": 1234,
  "product_id": 5678,
  "quantity":3,
  "payment_type": "mastercard"
}

       它可能有這樣一個schema,它定義了這五個字段:

{
  "type": "record",
  "doc":"This event records the sale of a product",
  "name": "ProductSaleEvent",
  "fields" : [
    {"name":"time", "type":"long", "doc":"The time of the purchase"},
    {"name":"customer_id", "type":"long", "doc":"The customer"},
    {"name":"product_id", "type":"long", "doc":"The product"},
    {"name":"quantity", "type":"int"},
    {"name":"payment",
     "type":{"type":"enum",
         "name":"payment_types",
             "symbols":["cash","mastercard","visa"]},
     "doc":"The method of payment"}
  ]
}

       下面介紹如何使用這些schema。你將把這樣的schema與每個Kafka topic關聯起來。你可以將該schema想象成關係數據庫表的schema,給出生成到topic中的數據的需求,以及如何從topic讀取數據的說明。
       這些schema最終服務於許多關鍵地點:
(1)它們讓數據流的生產者或消費者知道事件中需要哪些字段,以及每個字段的類型。
(2)They document the usage of the event and the meaning of each field in the “doc” fields.
(3)它們保護下游數據消費者不受髒數據的影響,因爲主題中只允許有效數據。

       當只有一個數據主題和一個應用程序進行讀寫時,schema的價值就不那麼明顯了。然而,當關鍵數據流在系統中流動,數十或數百個系統依賴於此時,簡單的數據推理工具就會產生巨大的影響。
       但是首先,您可能會問爲什麼我們需要schema?現代的大數據世界不都是關於非結構化數據的嗎?以任何方便的形式轉儲數據,然後在查詢數據時進行解析?

爲什麼需要Schemas

       我認爲,如果正確地使用模式,那麼它將是一個巨大的福音,可以保持數據的整潔,並使每個人都更加敏捷。對模式的許多反應來自兩個因素——關係數據庫中的歷史限制,這使得模式更改變得困難;以及許多現代分佈式基礎設施的不成熟,這些基礎設施還沒有時間完成語義層的建模。
       下面是schemas的一些示例。

魯棒性

       這種將數據建模爲流的體系結構的主要優點之一是應用程序是解耦的。應用程序生成一個事件流,在不知道訂閱這些流的對象的情況下捕捉髮生的事件。
       但在這樣一個世界裏,你怎麼能推理出數據的正確性呢?在沒有任何實際schema的情況下,數據流的新生成程序將盡力模仿現有數據,但是會出現不一致的情況——某些神奇的字符串常量不會被一致地複製,重要的字段會被忽略,等等。

清晰

       更糟糕的是,數據的實際含義變得模糊,而且常常被不同的應用程序誤解,因爲沒有關於字段含義的真正規範文檔。一個人以一種方式解釋一個字段並相應地填充它,另一個人以不同的方式解釋它。
       通常情況下,最終會得到一種非正式的白話“模式”,通過wiki或電子郵件在用戶之間傳遞數據,但如果沒有更新這種定義,這種schema就會被丟棄。我們發現缺乏文檔會導致人們猜測字段的含義,當猜測錯誤時,這不可避免地會導致錯誤和錯誤的數據分析。

兼容性

       模式還有助於解決組織範圍的數據流中最困難的問題之一:對數據格式的更改進行建模和處理。schema在某個時間點定義,但數據需要隨着業務和代碼的發展而發展。總是會有新的字段、數據表示方式的更改或新的數據流。這是數據庫通常忽略的問題。數據庫表的所有行都有一個schema。但是,如果您編寫的許多應用程序都在不同的時間發生變化並進行schema的演化,那麼這種嚴格的定義就無法工作。如果有幾十個應用程序都使用一箇中央數據流,那麼它們就不能同時更新。、
       隨着越來越多的人使用這些數據以及不同數據流的數量的增加,管理這些更改變得更加複雜。當然,添加一個新字段是安全的更改,但是刪除一個字段是安全的的嗎?重命名已存在的field呢?將字段從字符串更改爲數字呢?
       Hadoop可以使用Avro或列式存儲文件格式(如Parquet或ORC)“按原樣”加載數據。因此,可以非常自動地從數據流加載數據,但是當格式發生變化時會發生什麼呢?是否需要重新處理所有歷史數據以將其轉換爲新格式?當涉及到數百tb的數據時,這可能是相當大的工作量。您如何知道給定的更改是否需要這樣做?
       schema使Hadoop或Cassandra等具有靈活數據格式的系統能夠跟蹤上游數據更改,並簡單地將這些更改傳播到自己的存儲中,而無需昂貴的重新處理。Schemas提供了一種機制,用於推斷哪些格式更改是兼容的(因此不需要重新處理),哪些是不兼容的。
       我們發現,大多數實現了大型流平臺而沒有schema控制數據正確性的人都導致了嚴重的規模不穩定。在與Kafka這樣的系統一起使用時,這些兼容性破壞通常是特別痛苦的,因爲事件的生產者甚至可能不知道所有的使用者,所以手動測試兼容性可能很快就變得不可能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章