Apache Avro & Avro Schema簡介

帥氣型男發表於2020-07-15

為什麼需要schema registry?

首先我們知道:

  • Kafka將位元組作為輸入併發布
  • 沒有資料驗證

 

但是:

  • 如果Producer傳送了bad data怎麼辦?
  • 如果欄位被重新命名怎麼辦?
  • 如果資料型別改變了怎麼辦?

這些情況都會導致consumer break

 

所以:

  • 我們需要資料能夠自我描述
  • 我們需要能夠在不破壞下游消費者的情況下演化資料
  • 能夠拒絕壞資料

 

為什麼不在kafka broker收到訊息時驗證訊息,而是使用schema registry?

由下面兩幅圖可以看到,schema registry是獨立於kafka的一個元件。

Kafka Core:

 

 

 

 

Confluent Components -Schema Registry:

 

 

 

 

為什麼schema registry不整合在kafka broker,因為這樣會打破kafka一些優秀的特性:

  • Kafka不解析或讀取你的資料(沒有使用CPU)
  • Kafka將位元組作為輸入,而不需要事件將它們載入到記憶體中(稱為零拷貝) 。什麼是零拷貝,移步至https://www.cnblogs.com/fangjb/p/13271886.html
  • 就Kafka而言,它甚至不知道你的資料是否是整數或是字串。

 

所以:

  • Schema Registry需要是獨立的元件
  • 生產者和消費者需要能夠與之對話
  • 必須商定通用的資料格式
  • 它需要支援schema
  • 它需要支援進化
  • 它需要是輕量級的

 

Solution:

Confluent Schema Registry

Apache Avro as the data format

 

Apache Avro& Avro Schema介紹

  • Apache Avro是一個資料序列化系統。
  • 可以將Avro看作是JSON附帶一個schema
  • Avro schema使用Json來定義
  • Avro依賴於schema

Avro優點:

1.豐富的資料結構

2.使用快速的壓縮二進位制資料格式

3.schema隨資料一起出現

4.schema可以以安全的方式隨時間進化(schema evolution)

5. Document嵌入到schema中

Avro缺點:

1.某些語言對Avro的支援可能缺乏

2.不使用avro工具就不能“列印”資料(因為壓縮了和序列化)

 

資料型別

Schema 定義了基本資料型別和複雜資料型別,其中複雜資料型別包含不同屬性。通過各種資料型別使用者可以自定義豐富的資料結構

基本型別:

型別

含義

null

沒有值

boolean

布林值

int

32位有符號整數

long

64位有符號整數

float

單精度(32位)的IEEE 754浮點數

double

雙精度(64位)的IEEE 754浮點數

bytes

8位無符號位元組序列

string

字串

 

複雜型別

Avro提供了6種複雜型別。分別是Record,Enum,Array,Map,Union和Fixed。

 

Record型別:

Record型別使用的型別名字是 “record”,還支援其它屬性的設定:

  • name(必填):record型別的名字
  • namespace:名稱空間(可選),相當於java中的包名
  • doc:這個型別的文件說明(可選)
  • aliases:record型別的別名,是個字串陣列(可選)
  • fields(必填):record型別中的欄位,是個物件陣列。每個欄位需要以下屬性:
  • name(必填):欄位名字
  • doc:欄位說明文件(可選)
  • type(必填):一個schema的json物件或者一個型別名字
  • default:預設值(可選)
  • order:排序(可選),只有3個值ascending(預設),descending或ignore
  • aliases:別名,字串陣列(可選)

 一個record例子:

{
        "type": "record",
        "namespace": "com.aaa",
        "name": "Employee",
        "fields": [
          { "name": "id", "type": "string"},
          { "name": "first_name", "type": "string", "default": ""},
          { "name": "last_name", "type": "string", "default":""}
        ]
   }

 

Enum

列舉型別的型別名字是”enum”,還支援其它屬性的設定:

  • name:列舉型別的名字(必填)
  • namespace:名稱空間(可選)
  • aliases:字串陣列,別名(可選)
  • doc:說明文件(可選)
  • symbols:字串陣列,所有的列舉值(必填),不允許重複資料。

一個列舉例子:

{
  "type": "enum",
  "name": "customer_status",
  "symbols": [
    "BRONZE",
    "SILVER",
    "GOLD"
  ]
}

 

Array

陣列型別的型別名字是”array”並且只支援一個屬性:

items:陣列元素的schema

一個陣列例子:

{
    "name": "email", 
    "type": "array", 
    "items": "string"
}

 

Map

Map是一種定義keys和values列表的方法,其中keys是字串.

Example: secrets questions

  • “What’s your favourite color?”: “green”
  • “Where were you born?”: “Tapei”
  • “Who you love most?”: “My wife”

 

Map型別的型別名字是”map”並且只支援一個屬性:

values:map值的schema

Map的key必須是字串。

一個Map例子:

{
    "name": "secrets",
    "type": "map", 
    "values": "long"
}

 

Union

組合型別,表示各種型別的組合,使用陣列進行組合。比如[“null”, “string”]表示型別可以為null或者string。

組合型別的預設值是組合型別的第一個元素,因此如果一個組合型別包括null型別,那麼null型別一般都會放在第一個位置,這樣子的話這個組合型別的預設值就是null。

組合型別中不允許同一種型別的元素的個數不會超過1個,除了record,fixed和enum。比如組合類中有2個array型別或者2個map型別,這是不允許的。

組合型別不允許巢狀組合型別

相關文章