為什么需要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類型,這是不允許的。
組合類型不允許嵌套組合類型