【Kafka 小試】Kafka 高可用機制
1Kafka不是完全同步,也不是完全異步,是一種特殊的ISR(In Sync Replica)。
2ISR(in-sync replica) 就是 Kafka 爲某個分區維護的一組同步集合,即每個分區都有自己的一個 ISR 集合,處於 ISR 集合中的副本,意味着 follower 副本與 leader 副本保持同步狀態,只有處於 ISR 集合中的副本纔有資格被選舉爲 leader。
3複製代碼
4
Kafka 的 Replica
- kafka 的 topic 可以設置有 n 個副本(replica),副本數最好要小於等於 broker 的數量,也就是要保證一個 broker 上的 replica 最多有一個。
- 創建副本的單位是 topic 的分區,每個分區有 1 個 leader 和 0 到 n-1follower,Kafka 把多個 replica 分爲 Lerder replica 和 follower replica。
- 當 producer 在向 topic partition 中寫數據時,根據 ack 機制,默認 ack=1,只會向 leader 中寫入數據,然後 leader 中的數據會複製到其他的 replica 中,follower 會週期性的從 leader 中 pull 數據,但是對於數據的讀寫操作都在 leader replica 中,follower 副本只是當 leader 副本掛了後才重新選取 leader,follower 並不向外提供服務。
Kafka ISR 機制
ISR 副本: 就是能跟首領副本基本保持一致的跟隨副本,如果同步的速度太慢的話,就會被踢出 ISR 副本。
副本同步:
-
LEO(last end offset):日誌末端位移,記錄了該副本對象底層日誌文件中下一條消息的位移值,副本寫入消息的時候,會自動更新 LEO 值。如果 LE0 爲 2 的時候,當前的 offset 爲 1。
-
HW(high watermark):高水印值,HW 一定不會大於 LEO 值,小於 HW 值的消息被認爲是 “已提交” 或“已備份”的消息,並對消費者可見。
-
producer 向 leader 發送消息,之後寫入到 leader,leader 在本地生成 log,之後 follow 從 leader 拉取消息,follow 寫入到本地的 log 中,會給 leader 返回一個 ack 信號,一旦收到了 ISR 中的所有的 ack 信號,就會增加 HW,然後 leader 返回給 producer 一個 ack。
Kafka 的複製機制
kafka 每個分區都是由順序追加的不可變的消息序列組成,每條消息都一個唯一的 offset 來標記位置。
kafka 中的副本機制是以分區粒度進行復制的,在 kafka 中創建 topic 的時候,都可以設置一個複製因子 (replica count),這個複製因子決定着分區副本的個數,如果 leader 掛掉了,kafka 會把分區主節點 failover 到其他副本節點,這樣就能保證這個分區的消息是可用的。leader 節點負責接收 producer 發過來的消息,其他副本節點(follower)從主節點上拷貝消息。
[站外圖片上傳中...(image-31f1f9-1614765714779)]
kakfa 日誌複製算法提供的保證是當一條消息在 producer 端認爲已經 committed 的之後,如果 leader 節點掛掉了,其他節點被選舉成爲了 leader 節點後,這條消息同樣是可以被消費到的。
關鍵配置: unclean.leader.election.enable
1Indicates whether to enable replicas not in the ISR set to be elected as leader as a last resort, even though doing so may result in data loss
2
3Type: boolean
4Default: false
5Valid Values:
6Importance: high
7Update Mode: cluster-wide
8複製代碼
9
默認爲 false
, 即允許不在 isr 中 replica 選爲 leader,這個配置可以全局配置,也可以在 topic 級別配置。
這樣的話,leader 選舉的時候,只能從 ISR 集合中選舉,集合中的每個點都必須是和 leader 消息同步的,也就是沒有延遲,分區的 leader 維護 ISR 集合列表,如果某個點落後太多,就從 ISR 集合中踢出去。
producer 發送一條消息到 leader 節點後, 只有當 ISR 中所有 Replica 都向 leader 發送 ACK 確認這條消息時,leader 才 commit,這時候 producer 才能認爲這條消息 commit 了,正是因爲如此,kafka 客戶端的寫性能取決於 ISR 集合中的最慢的一個 broker 的接收消息的性能,如果一個點性能太差,就必須儘快的識別出來,然後從 ISR 集合中踢出去,以免造成性能問題。
如何判斷副本不會被移除 ISR 集合?
replica.lag.max.messages
: follower 副本最大落後 leader 副本的消息數。(0.9.0.0 版本後移除)。
replica.lag.time.max.ms
: 不僅指自從上次從副本獲取請求以來經過的時間,而且還指自上次捕獲副本以來的時間。
設置replica.lag.max.messages
爲 3,只要 follower 只要不落後 leader 大於 2 條消息,就然後是跟得上 leader 的節點,就不會被踢出去。
設置 replica.lag.time.max.ms 爲 300ms, 意味着只要 follower 在每 300ms 內發送 fetch 請求,就不會被認爲已經 dead ,不會從 ISR 集合中踢出去。
結語
Replica 的目的就是在發生意外時及時頂上,leader 失效後,就需要從 follower 中馬上選一個新的 leader 。選舉時優先從 ISR 中選定,因爲這個列表中 follower 的數據是與 leader 同步的,從他們中間選取可以保證數據完整 。
但如果不幸 ISR 列表中的 follower 都不行了,就只能從其他 follower 中選取,這時就有數據丟失的可能了,因爲不確定這個 follower 是否已經把 leader 的數據都複製完成了。
還有一種極端情況,就是所有副本都失效了,這時有兩種方案:
-
等待 ISR 中的一個活過來,選爲 Leader,數據可靠,但活過來的時間不確定 。
-
選擇第一個活過來的 Replication,不一定是 ISR 中的,選爲 leader,以最快速度恢復可用性,但數據不一定完整。
Kafka 支持通過配置選擇使用哪一種方案,可以根據可用性和一致性進行權衡。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://juejin.cn/post/6939767567456157733?utm_source=gold_browser_extension