Kafka消息規範

Kafka作為一個消息隊列,有其自己定義消息的格式。Kafka中的消息採用ByteBuf,之所以採用ByteBuf這種緊密的二進位存儲格式是因為這樣可以節省大量的空間。畢竟如果使用Java類的格式來定義消息對象將會浪費大量的空間(Java對象除了本身屬性所佔的空間外,還存在一些Header,還會存在一些補齊)。

V2消息格式

Kafka的消息格式經歷了V0、V1以及V2版本。V0沒有時間戳的欄位,導致很難對過期的消息進行判斷。V0、V1存在很多固定長度的欄位,這些欄位在實際中往往佔用很少,造成浪費,因此V2將其中的很多定義長度的欄位設計成可變長度。

可變長度的設計借鑒了Zig-zag編碼格式,最高位用來表示當前位元組是否已經是某個數編碼的最後一個位元組(1代表不是,0代表是)。

  • 消息總長度:整個消息的長度,方便消息的遍歷以及獲取其總長度
  • 屬性:保留欄位,暫時無作用
  • 時間戳增量:消息距離Batch時間戳的增量,不再使用固定8位元組的時間戳,該欄位將會大大降低消息的存儲空間
  • 位移增量:消息距離Batch位移的增量
  • key length:消息key內容的長度
  • key:消息key的內容
  • value size:消息內容的長度
  • value:消息內容
  • header:header的個數
  • heders:具體的header,對用戶可見,可做消息路由或者某些消息元數據的載體。
V2消息批次格式RecordBatch

一個消息批次包含若干個消息組成,其實Kafka的日誌文件就是用若干個消息批次組成的,kafka不是直接在消息層面上操作的,它總是在消息批次層面上進行寫入。

  • 起始位移:Kafka日誌分區中的offset
  • 長度:該消息批次的長度
  • 分區leader版本號
  • 版本號:目前該值是2
  • CRC:CRC校驗碼,用來確認消息在傳輸過程中不會被篡改,該欄位在V0、V1中是在消息層面的,但對每一條消息都進行CRC,將會造成CPU的浪費
  • 屬性:該欄位在V0和V1的版本中也是存在於消息層面,在V2中低三位依然表示消息的壓縮類型,第4位依然是時間戳類型(一種是客戶端指定時間戳,另一種是有kafka broker指定時間戳),第5位和第6位分別表示新引入的事務類型和控制類型
  • 起始時間戳:batch中第一條消息的時間戳
  • 最大時間戳:batch中最後一條消息的時間戳
  • PID、producer epoch、起始序列號:序列號的引入為了生產消息的冪等性,Kafka用它來判斷消息是否已經提交,防止重複生產消息。PID代表冪等性producer的ID,producer epoch表示producer攜帶的當前版本號,broker使用這兩個欄位判斷producer是否有效,防止過期的producer生產消息