Partition Recovery機制
每個Partition會在磁盤記錄一個RecoveryPoint, 記錄已經flush到磁盤的最大offset。broker fail 重啟時,會進行loadLogs。 首先會讀取該Partition的RecoveryPoint,找到包RecoveryPoint的segment及以后的segment, 這些segment就是可能沒有 完全flush到磁盤segments。然后調用segment的recover,重新讀取各個segment的msg,並重建索引。這樣做的優點:
- 以segment為單位管理Partition數據,方便數據生命周期的管理,刪除過期數據簡單
- 在程序崩潰重啟時,加快recovery速度,只需恢復未完全flush到磁盤的segment
- 通過index中offset與物理偏移映射,用二分查找能快速定位msg,並且通過分多個Segment,每個index文件很小,查找速度更快。
Partition Replica同步機制
- Partition的多個replica中一個為Leader,其余為follower
- Producer只與Leader交互,把數據寫入到Leader中
- Followers從Leader中拉取數據進行數據同步
- Consumer只從Leader拉取數據
ISR:所有不落后的replica集合, 不落后有兩層含義:距離上次FetchRequest的時間不大於某一個值或落后的消息數不大於某一個值, Leader失敗后會從ISR中選取一個Follower做Leader
數據可靠性保證
當Producer向Leader發送數據時,可以通過acks參數設置數據可靠性的級別:
- 0: 不論寫入是否成功,server不需要給Producer發送Response,如果發生異常,server會終止連接,觸發Producer更新meta數據;
- 1: Leader寫入成功后即發送Response,此種情況如果Leader fail,會丟失數據
- 1: 等待所有ISR接收到消息后再給Producer發送Response,這是最強保證僅設置acks=-1也不能保證數據不丟失,當Isr列表中只有Leader時,同樣有可能造成數據丟失。要保證數據不丟除了設置acks=-1, 還要保 證ISR的大小大於等於2
request.required.acks:設置為-1 等待所有ISR列表中的Replica接收到消息后采算寫成功; min.insync.replicas: 設置為大於等於2,保證ISR中至少有兩個Replica Producer要在吞吐率和數據可靠性之間做一個權衡
數據一致性保證
一致性定義:若某條消息對Consumer可見,那么即使Leader宕機了,在新Leader上數據依然可以被讀到
- HighWaterMark簡稱HW: Partition的高水位,取一個partition對應的ISR中最小的LEO作為HW,消費者最多只能消費到HW所在的位置,另外每個replica都有highWatermark,leader和follower各自負責更新自己的highWatermark狀態,highWatermark <= leader. LogEndOffset
- 對於Leader新寫入的msg,Consumer不能立刻消費,Leader會等待該消息被所有ISR中的replica同步后,更新HW,此時該消息才能被Consumer消費,即Consumer最多只能消費到HW位置
這樣就保證了如果Leader Broker失效,該消息仍然可以從新選舉的Leader中獲取。對於來自內部Broker的讀取請求,沒有HW的限制。同時,Follower也會維護一份自己的HW,Folloer.HW = min(Leader.HW, Follower.offset)