為了保證可用性,Kafka 的分區是多副本的,可以在創建分區時通過 replication-factor 參數指定該分區的副本數,某一副本丟失并不會造成實際數據的丟失,從其他副本獲取數據即可。但同時引出了另外一個問題,各個副本之間的數據如何保證一致性?
首先,分區的副本根據角色的不同可分為:Leader 副本、 Follower 副本
- Leader 副本:Leader 負責與 Producer 和 Consumer 交互,即數據的讀寫。
- Follower 副本:被動地備份 leader 副本中的數據,不與 Client 端做任何交互。
另外,不得不提的是 ISR,即(in-sync Replica)副本同步隊列:它包含了 Leader 副本和所有與 Leader 副本保持同步的 Follower 副本。那么如何判斷 Follower 副本與 Leader 是同步的? Leader 副本和 Follower 副本有兩個重要的屬性值,如圖 LEO 日志末端位移和 HW 水位線。
* LEO(log end offset):記錄日志的末端位移值,即數據寫到的最新的位置。
* HW(high watermark):取最小的 LEO 作為 HW,即 Committed 過的最新數據。consumer 最多只能消費到 HW 所在的位置,因為小于等于 HW 值的數據才是 Committed 備份過的。
我們再來看一下,LEO和HW的更新時機
Leader 除了 HW 和 LEO 還會有 RemoteLEO 這個屬性,表示 Follwer 的 LEO。Leader 在以下情況下會更新這三個屬性。
* LEO:Producer 端有數據寫入成功時 Leader 會自動地更新 LEO 值
* HW:有請求的時候(Producer 或 Follower 的請求)會對比自己 LEO和Remote LEO 取小值更新HW
* Remote LEO:Leader 處理 Follower 的 Fetch 請求時,將 Remote LEO 更新為 Follwer 請求中附帶的 LEO 值。
Follower 只有 HW 和 LEO 兩個屬性,更新時機為:
* LEO:同樣是有數據寫入成功時就會自動地更新 LEO 值。
* HW:Follower 更新 HW 發生在其更新 LEO 之后,一旦 Follower 向 log 寫完數據,它會嘗試更新它自己的 HW 值。更新的條件是比較當前 LEO 值與 Response 中 Leader 的 HW 值,取兩者的小者作為新的 HW 值,如圖的 HW:1 會在此時更新為 2。
更多關于“大數據培訓”的問題,歡迎咨詢千鋒教育在線名師。千鋒教育多年辦學,課程大綱緊跟企業需求,更科學更嚴謹,每年培養泛IT人才近2萬人。不論你是零基礎還是想提升,都可以找到適合的班型,千鋒教育隨時歡迎你來試聽。