Kafka的Producer、Broker和Consumer之間採用的是一套自行設計的基於TCP層的協議。Kafka的這套協議徹底是爲了Kafka自身的業務需求而定製的,而非要實現一套相似於Protocol Buffer的通用協議。本文將介紹這套協議的相關內容。下面我本身加了一張圖 數組
Kafka中兩個角色之間通信的基本單位是Request/Response,Request和Response的基本結構以下: 服務器
RequestOrResponse => MessageSize (RequestMessage | ResponseMessage)
其中各字段的含義爲: 網絡
名稱 | 類型 | 描述 |
---|---|---|
MessageSize | int32 | 表示RequestMessage或者ResponseMessage的長度 |
RequestMessage/ResponseMessage | - | 表示Request或者Response的內容,在下面將會介紹其具體格式。 |
這個結構定義了通信雙方交換數據的基本結構。通信的過程能夠簡單地表示爲:客戶端打開與服務器端的Socket,而後往Socket寫入一個int32的數字表示此次發送的Request有多少字節,而後繼續往Socket中寫入對應字節數的數據。服務器端先讀出一個int32的整數從而獲取此次Request的大小,而後讀取對應字節數的數據從而獲得Request的具體內容。服務器端處理了請求後,也用一樣的方式來發送響應。 數據結構
RequestMessage的結構以下: app
RequestMessage => ApiKey ApiVersion CorrelationId ClientId Request
名稱 | 類型 | 描述 |
---|---|---|
ApiKey | int16 | 表示此次請求的API編號 |
ApiVersion | int16 | 表示請求的API的版本,有了版本後就能夠作到後向兼容 |
CorrelationId | int32 | 由客戶端指定的一個數字惟一標示此次請求的id,服務器端在處理完請求後也會把一樣的CorrelationId寫到Response中,這樣客戶端就能把某個請求和響應對應起來了。 |
ClientId | string | 客戶端指定的用來描述客戶端的字符串,會被用來記錄日誌和監控,它惟一標示一個客戶端。 |
Request | - | Request的具體內容。 |
ResponseMessage的結構以下: 分佈式
ResponseMessage => CorrelationId Response
名稱 | 類型 | 描述 |
---|---|---|
CorrelationId | int32 | 對應Request的CorrelationId。 |
Response | - | 對應Request的Response,不一樣的Request的Response的字段是不同的。 |
Kafka是一個分佈式消息系統,Producer生產消息並推送(Push)給Broker,而後Consumer再從Broker那裏取走(Pull)消息。Producer生產的消息就是由Message來表示的,對用戶來說,它就是鍵-值對,來看看它的結構。 編碼
Message => Crc MagicByte Attributes Key Value
名稱 | 類型 | 描述 |
---|---|---|
CRC | int32 | 表示這條消息(不包括CRC字段自己)的校驗碼 |
MagicByte | int8 | 表示消息格式的版本,用來作後向兼容,目前值爲0 |
Attributes | int8 | 表示這條消息的元數據,目前最低兩位用來表示壓縮格式 |
Key | bytes | 表示這條消息的Key,能夠爲null |
Value | bytes | 表示這條消息的Value。Kafka支持消息嵌套,也就是把一條消息做爲Value放到另一條消息裏面。 |
MessageSet用來組合多條Message,它在每條Message的基礎上加上了Offset和MessageSize,其結構是: spa
MessageSet => [Offset MessageSize Message]
它的含義是MessageSet是個數組,數組的每一個元素由三部分組成,分別是Offset,MessageSize和Message,它們的含義分別是: 設計
名稱 | 類型 | 描述 |
---|---|---|
Offset | int64 | 它用來做爲log中的序列號,Producer在生產消息的時候還不知道具體的值是什麼,能夠隨便填個數字進去 |
MessageSize | int32 | 表示這條Message的大小 |
Message | - | 表示這條Message的具體內容,其格式見上一小節。 |
Kafka支持下面幾種壓縮方式, 日誌
壓縮方式 | 編碼 |
---|---|
不壓縮 | 0 |
Gzip | 1 |
Snappy | 2 |
LZ4 | 3 |
其中編碼就是Message的Attribute的最低兩位的值。
由於單條消息中重複內容可能很少,因此一般把多條消息放在一塊兒組成MessageSet,而後再把MessageSet放到一條Message裏面去,從而提升壓縮比率。
Kafka的通信協議中不含Schema,格式也比較簡單,這樣設計的好處是協議自身的Overhead小,再加上把多條Message放在一塊兒作壓縮,提升壓縮比率,從而在網絡上傳輸的數據量會少一些。