版權聲明:本套技術專欄是做者(秦凱新)平時工做的總結和昇華,經過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和集羣環境容量規劃等內容,請持續關注本套博客。版權聲明:禁止轉載,歡迎學習。QQ郵箱地址:1120746959@qq.com,若有任何商業交流,可隨時聯繫。java
從0.8.x版本開始到如今的1.1.x版本,Kafka的消息格式也經歷了3個版本。每次版本的改變,都預示着新的優化。那麼Broker做爲Kafka服務載體,承擔了消息協議的響應和接收。緩存
對齊填充計算方法: HotSpot 的對齊方式爲 8 字節對齊,不足的須要 Padding 填充對齊, 公式:架構
(對象頭 + 實例數據 + padding)% 8 == 0 (0<= padding <8)
複製代碼
對一個java對象,至少須要16字節對象頭部(對於64位JVM對象一般由8字節的Word組成)。app
版本號: V0版本magic=0,V1版本magic=1,V2版本magic=2學習
屬性:消息壓縮類型。目前僅支持3種壓縮方法。優化
0X00 未啓動壓縮 0x01 GZIP 0x02 Snappy 0x03 LZ4
複製代碼
注意key長度字段和value長度字段是固定的,沒有也佔用4個字節,來存 -1編碼
除了key值和value值外,能夠統稱爲是消息頭部信息(header),總共佔用14字節。spa
假設:存在Key值 爲key , value值爲 value (一個字符一個字節,共8個字節)
則 header 14 字節 + 值 8字節 = 22字節
當key爲空時,則佔用 19字節
複製代碼
日誌頭部(LOG_OVERHEAD):每一個Record(v0和v1版)一定對應一個offset和message size。每條消息都一個offset用來標誌它在partition中的偏移量,這個offset是邏輯值,而非實際物理偏移值,message size表示消息的大小,這二者的一塊兒被稱之爲日誌頭部(LOG_OVERHEAD),固定爲12B設計
總結:一條消息一定包含LOG_OVERHEAD和消息體兩部分。最小佔用12B+14B=26B,在不包含key值和Value值的狀況下。3d
若key =key , value=value 則佔用26(純格式)+8(值空間)=34B
首先建立一個partition數和副本數都爲1的topic,名稱爲「msg_format_v0」,
而後往msg_format_v0中發送一條key=」key」,value=」value」的消息,以後查看對應的日誌:
-rw-r--r-- 1 root root 34 Apr 26 02:52 00000000000000000000.log
再次插入一條key=null, value=」value」的消息:
-rw-r--r-- 1 root root 65 Apr 26 02:56 00000000000000000000.log
複製代碼
總結:發送每一條消息必須攜帶12字節LOG_OVERHEAD,是分散的消息格式設計,沒有體現集合的味道。
舉例以下: 發送第一條key=」key」,value=」value」的消息,則佔用22+12+8=42B 發送第二條key=null,value=」value」的消息,,則佔用12+22+5=39B
合在一塊兒發則爲:42+39=81B
kafka從0.11.0版本開始所使用的消息格式版本爲v2,這個版本的消息相比於v0和v1的版本而言改動很大,同時還參考了Protocol Buffer而引入了變長整型(Varints)和ZigZag編碼。
Varints是使用一個或多個字節來序列化整數的一種方法,數值越小,其所佔用的字節數就越少。ZigZag編碼以一種鋸齒形(zig-zags)的方式來回穿梭於正負整數之間,以使得帶符號整數映射爲無符號整數,這樣可使得絕對值較小的負數仍然享有較小的Varints編碼值,好比-1編碼爲1,1編碼爲2,-2編碼爲3。
zig-zags 會固定的將每個字節的第一位留做特殊用途,代表該字節是不是最後一個字節,若最高位是1,表示編碼還沒有結束。所以實際上也僅有7位用於實際的編碼,即0-127。另外考慮 -1 ,1, -2, 2 對應 1,2, 3, 4。所以,0-63之間的數字佔1個字節,64-8191之間的數字佔2個字節,8192-1048575之間的數字佔3個字節。kafka broker的配置message.max.bytes的默認大小爲1000012(Varints編碼佔3個字節)。
注意的是Varints並不是一直會省空間,一個int32最長會佔用5個字節(大於默認的4字節),一個int64最長會佔用10字節(大於默認的8字節)
總結 :v2版本的消息格式去掉了crc字段,另外增長了length(消息總長度)、timestamp delta(時間戳增量)、offset delta(位移增量)和headers信息,而且attributes被棄用。
v2版本對於消息集(RecordBatch)作了完全的修改,總共佔用了61個字節,好比:把crc校驗放在了Batch這一層,冪等性引入,使用PID標識。epoch引入,標識當前版本。看似增大了消息的容量大小,從大規模消息來算的話,卻帶來了質的飛躍,由於一條純消息格式僅佔用7字節了,而V1佔用22字節,V0佔用14字節。
first offset:表示當前RecordBatch的起始位移。
length:計算partition leader epoch到headers之間的長度。
partition leader epoch:用來確保數據可靠性,詳細能夠參考KIP-101
magic:消息格式的版本號,對於v2版本而言,magic等於2。
attributes:消息屬性,注意這裏佔用了兩個字節。低3位表示壓縮格式,能夠參考v0和v1;第4位表示時間戳類型;第5位表示此RecordBatch是否處於事務中,0表示非事務,1表示事務。第6位表示是不是Control消息,0表示非Control消息,而1表示是Control消息,Control消息用來支持事務功能。
last offset delta:RecordBatch中最後一個Record的offset與first offset的差值。主要被broker用來確認RecordBatch中Records的組裝正確性。
first timestamp:RecordBatch中第一條Record的時間戳。
max timestamp:RecordBatch中最大的時間戳,通常狀況下是指最後一個Record的時間戳,和last offset delta的做用同樣,用來確保消息組裝的正確性。
producer id:用來支持冪等性,詳細能夠參考KIP-98。
producer epoch:和producer id同樣,用來支持冪等性。
first sequence:和producer id、producer epoch同樣,用來支持冪等性。
records count:RecordBatch中Record的個數。
複製代碼
V1 版本的弊端:
V2 新型架構優勢:
本篇技術專欄很是難寫,必須綜合大量資料和實驗才能夠驗證。辛苦成文,各自珍惜。
秦凱新 於深圳