kafka的副本機制
partition的副本被稱為replica,每個分割槽可以有多個副本,並且在副本集中會存在一個leader副本,所有的讀寫請求都會通過leader完成,follower複製只負責備份資料。
副本會均勻分配到多臺broker上,當leader節點掛掉之後,會從副本集中重新選出一個副本作為leader繼續提供服務
副本分配演算法:
n個broker 將第i個partition的第j個副本分配到第((i+j)mod n)個broker上
kafka副本機制中的概念:
- leader副本:響應客戶端的讀寫請求
- follow副本:備份leader的資料,不進行讀寫操作
- ISR副本:leader副本和所有能夠與leader副本保持基本同步的follow副本,如 果follow副本和leader副本資料同步速度過慢,該follow將會被T出ISR副本
ISR集合中的副本必須滿足的條件:
- 副本所在的節點與zk相連
- 副本的最後一條訊息和leader副本的最後一條訊息的差值不能超過閾值replica.lag.time.max.ms:如果該follower在此時間間隔之內沒有追上leader,則該follower將會被T出ISR
副本同步時的兩個重要概念
- LEO(Last end offset) 記錄了該副本底層日誌中的下一條訊息的offset,例如LEO為10,那麼當前的offset為9
- HW (High water)標記著可消費的訊息,對於同一個副本而言HW不會大於LEO,小於等於HW的訊息將會被認為是已備份的。
副本協同機制
producer將訊息傳送到該partition的leader上,leader會把訊息寫入其本地log,每個follower都從leader pull資料。在follower收到訊息並且將訊息寫入本地log之後會向leader傳送ack,一旦leader收到了ISR中所有replica的ACK,該訊息就被認為已經commit了,leader會增加HW並向producer傳送ACK
過程如下所示
follower傳送fetch請求,並帶上自己的LEO leader端的操作 1.當producer傳送一個訊息給leader之後,leader會把訊息寫入磁碟 2.然後leader會更新LEO,這時候嘗試更新HW,HW是取LEO和remoteLEO的較小值,這時候HW依然為0.(remoteLEO取所有Follower發過來的offset中最小的一個) 3.把訊息內容和當前的HW值傳送給follower副本
當收到響應之後,follower端的操作 1.將訊息寫入本地log,同時更新LEO 2.比較本地LEO和返回的HW,比較他們取小值賦值給HW
第二次傳送fetch請求之後
leader 1.更新remoteLEO=1 2.更新HW為1 3.把資料和當前HW返回給follower,如果這時候沒有資料,則返回空
follower收到response之後 1.如果有資料則寫入本地日誌,並且更新LEO 2.更新HW的值 到目前為止,consumer就可以消費offset=0的訊息了