回覆列表
-
1 # 隔壁老佛爺
-
2 # 小馬過河Vizit
什麼是可靠性
對於訊息系統來說,所謂可靠性就是指訊息可以從生產者(producer)準確的送達到消費者(consumer)。可靠性保證有三個層次:
At most once 最多一次。訊息可能會丟失,但是決不重複。At least once 至少一次。訊息決不丟失,但可能會重複。Exactly once 恰好一次。這是最完美的,既不丟失,也不重複。如果要可靠的準確的傳達訊息,需要生產者程式,訊息系統和消費者程式相互合作。
什麼是一致性對於訊息系統來說,一致性是指,如果一個消費者c1讀到訊息m1的offset是x,那麼之後的任何消費者讀到的offset是x的訊息一定也是c1。
可以參看我的一個影片《分散式系統中的強一致性和弱一致性》
Kafka如何保證可靠性和一致性如果要可靠的準確的傳達訊息,需要生產者程式,訊息系統和消費者程式相互合作。
生產者程式 Producer
生產者需要確認訊息成功送達kafka的服務區broker,並且得到broker的返回訊息,確認訊息已經提交(commit)。如果沒有成功返回需要重發,直到傳送成功。
Kafka伺服器叢集 Cluster
Kafka的伺服器是一個叢集,叢集中至少需要包含3個以上的節點。透過主從備份可以保證不丟訊息。只要提交的訊息就保證不丟。
消費者程式 Consumer
消費者從Kafka讀取訊息以後要妥善處理。所謂妥善處理,就是完成自己獲取這一條訊息的目標,比如生成一條業務資料存入資料庫,或者傳送訊息到其他的系統。
1.Partition Recovery機制
每個Partition會在磁碟記錄一個RecoveryPoint, 記錄已經flush到磁碟的最大offset。當broker fail 重啟時,會進行loadLogs。 首先會讀取該Partition的RecoveryPoint,找到包含RecoveryPoint的segment及以後的segment, 這些segment就是可能沒有 完全flush到磁碟segments。然後呼叫segment的recover,重新讀取各個segment的msg,並重建索引。
優點
* 在程式崩潰重啟時,加快recovery速度,只需恢復未完全flush到磁碟的segment
* 透過index中offset與物理偏移對映,用二分查詢能快速定位msg,並且透過分多個Segment,每個index檔案很小,查詢速度更快。
2.Partition Replica同步機制
* Partition的多個replica中一個為Leader,其餘為follower
* Producer只與Leader互動,把資料寫入到Leader中
* Followers從Leader中拉取資料進行資料同步
* Consumer只從Leader拉取資料
ISR:所有不落後的replica集合, 不落後有兩層含義:距離上次FetchRequest的時間不大於某一個值或落後的訊息數不大於某一個值, Leader失敗後會從ISR中選取一個Follower做Leader。
3.資料可靠性保證
當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,具體引數設定:
4.資料一致性保證
一致性定義:若某條訊息對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)