Kafka 網絡中斷和網絡分區(qū)4種場景分析
摘要:本文主要帶來 4 種 Kafka 網絡中斷和網絡分區(qū)場景分析。
1. 單個 broker 節(jié)點和 leader 節(jié)點網絡中斷
網絡中斷前:
broker-1 和 broker-0(leader)間的網絡中斷后,單邊中斷,zk 可用(zk-1 為 leader,zk-0 和 zk-2 為 follower,zk-0 會不可用,但 zk 集群可用,過程中可能會引起原本連在 zk-0 上的 broker 節(jié)點會先和 zk 斷開,再重新連接其他 zk 節(jié)點,進而引起 controller 切換、leader 選舉等,此次分析暫不考慮這種情況),leader、isr、controller 都不變
az2 內的客戶端無法生產消費(metadata 指明 leader 為 broker-0,而 az2 連不上 broker-0),az1/3 內的客戶端可以生產消費,若 acks=-1,retries=1,則生產消息會失敗,error_code=7(REQUEST_TIMED_OUT)(因為 broker-1 在 isr 中,但無法同步數據),且會發(fā)兩次(因為 retries=1),broker-0 和 broker-2 中會各有兩條重復的消息,而 broker-1 中沒有;由于 broker-0 沒有同步數據,因此會從 isr 中被剔除,controller 同步 metadata 和 leaderAndIsr,isr 更新為 [2,0]
網絡恢復后,數據同步,更新 isr
2. 單個 broker 節(jié)點和 controller 節(jié)點網絡中斷
broker 和 controller 斷連,不影響生產消費,也不會出現(xiàn)數據不一致的情況
而當發(fā)生 leader 和 isr 變化時,controller 無法將 leader 和 isr 的變化更新給 broker,導致元數據不一致
broker-0 故障時,controller(broker-2)感知,并根據 replicas 選舉新的 leader 為 broker-1,但因為和 broker-1 網絡中斷,無法同步給 broker-1,broker-1 緩存的 leader 依然是 broker-0,isr 為 [1,2,0];當客戶端進行生產消費時,如果從 broker-2 拿到 metadata,認為 leader 為 1,訪問 broker-1 會返回 NOT_LEADER_OR_FOLLOWER;如果從 broker-1 拿到 metadata,認為 leader 為 0,訪問 broker-0 失敗,都會導致生產消費失敗
3. 非 controller 節(jié)點所在 az 被隔離(分區(qū))
zk-0 和 zk-1、zk-2 不通,少于半數,az1 內 zk 不可用,broker-0 無法訪問 zk,不會發(fā)生 controller 選舉,controller 還是在 broker-1
網絡恢復后,broker-0 加入集群,并同步數據
3.1 三副本 partition(replicas:[1,0,2]),原 leader 在 broker-1(或 broker-2)
az1 內:
broker-0 無法訪問 zk,感知不到節(jié)點變化,metadata 不更新(leader:1,isr:[1,0,2]),依然認為自己是 follower,leader 在 1;az1 內的客戶端無法生產消費
az2/3 內:
zk 可用,感知到 broker-0 下線,metadata 更新,且不發(fā)生 leader 切換(isr:[1,0,2] -> [1,2],leader:1);az2 和 az3 內的客戶端可正常生產消費
3.2 三副本 partition(replicas:[0,1,2]),原 leader 在 broker-0
az1 內:
zk-0 和 zk-1、zk-2 連接中斷,少于一半,az1 內 zk 集群不可用,Broker-0 連不上 zk,無法感知節(jié)點變化,且無法更新 isr,metadata 不變,leader 和 isr 都不變;az1 內客戶端可以繼續(xù)向 broker-0 生產消費
az2/3 內:
zk-1 和 zk-2 連通,zk 可用,集群感知到 broker-0 下線,觸發(fā) leader 切換,broker-1 成為新的 leader(時間取決于 zookeeper.session.timeout.ms),并更新 isr;az2/3 內的客戶端可以向 broker-1 生產消費
此時,該分區(qū)出現(xiàn)了雙主現(xiàn)象,replica-0 和 replica-1 均為 leader,均可以進行生產消費
若兩個隔離域內的客戶端都生產了消息,就會出現(xiàn)數據不一致的情況
示例:(假設網絡隔離前有兩條消息,leaderEpoch=0)
網絡隔離前:
az1 隔離后,分區(qū)雙主,az1 內的客戶端寫入 3 條消息:c、d、e,az2/3 內的客戶端寫入 2 條消息:f、g:
這里 leaderEpoch 增加 2,是因為有兩次增加 leaderEpoch 的操作:一次是 PartitionStateMachine 的 handleStateChanges to OnlinePartition 時的 leader 選舉,一次是 ReplicationStateMachine 的 handleStateChanges to OfflineReplica 時的 removeReplicasFromIsr
網絡恢復后:
由于 controller 在 broker-2,緩存和 zk 中的 leader 都是 broker-1,controller 會告知 broker-0 makerFollower,broker-0 隨即 add fetcher,會先從 leader(broker-1)獲取 leaderEpoch 對應的 endOffset(通過 OFFSET_FOR_LEADER_EPOCH),根據返回的結果進行 truncate,然后開始 FETCH 消息,并根據消息中的 leaderEpoch 進行 assign,以此和 leader 保持一致
待數據同步后,加入 isr,并更新 isr 為 [1,2,0]。之后在觸發(fā) preferredLeaderElection 時,broker-0 再次成為 leader,并增加 leaderEpoch 為 3
在網絡隔離時,若 az1 內的客戶端 acks=-1,retries=3,會發(fā)現(xiàn)生產消息失敗,而數據目錄中有消息,且為生產消息數的 4 倍(每條消息重復 4 次)
有前面所述可知,網絡恢復后,offset2-13 的消息會被覆蓋,但因為這些消息在生產時,acks=-1,給客戶端返回的是生產失敗的,因此也不算消息丟失
因此,考慮此種情況,建議客戶端 acks=-1
4. Controller 節(jié)點所在 az 被隔離(分區(qū))
4.1 Leader 節(jié)點未被隔離
網絡中斷后,az3 的 zk 不可用,broker-2(原 controller)從 zk 集群斷開,broker-0 和 broker-1 重新競選 controller
最終 broker-0 選舉為 controller,而 broker-2 也認為自己是 controller,出現(xiàn) controller 雙主,同時因連不上 zk,metadata 無法更新,az3 內的客戶端無法生產消費,az1/2 內的客戶端可以正常生產消費
故障恢復后,broker-2 感知到 zk 連接狀態(tài)發(fā)生變化,會先 resign,再嘗試競選 controller,發(fā)現(xiàn) broker-0 已經是 controller 了,放棄競選 controller,同時,broker-0 會感知到 broker-2 上線,會同步 LeaderAndIsr 和 metadata 到 broker-2,并在 broker-2 同步數據后加入 isr
4.2 Leader 節(jié)點和 controller 為同一節(jié)點,一起被隔離
隔離前,controller 和 leader 都在 broker-0:
隔離后,az1 網絡隔離,zk 不可用,broker-2 競選為 controller,出現(xiàn) controller 雙主,同時 replica-2 成為 leader,分區(qū)也出現(xiàn)雙主
此時的場景和 3.2 類似,此時生產消息,可能出現(xiàn)數據不一致
網絡恢復后的情況,也和 3.2 類似,broker-2 為 controller 和 leader,broker-0 根據 leaderEpoch 進行 truncate,從 broker-2 同步數據
加入 isr,然后通過 preferredLeaderElection 再次成為 leader,leaderEpoch 加 1
5. 補充:故障場景引起數據不一致
5.1 數據同步瞬間故障
初始時,broker-0 為 leader,broker-1 為 follower,各有兩條消息 a、b:
leader 寫入一條消息 c,還沒來得及同步到 follower,兩個 broker 都故障了(如下電):
之后 broker-1 先啟動,成為 leader(0 和 1 都在 isr 中,無論 unclean.leader.election.enable 是否為 true,都能升主),并遞增 leaderEpoch:
然后 broker-0 啟動,此時為 follower,通過 OFFSET_FOR_LEADER_EPOCH 從 broker-1 獲取 leaderEpoch=0 的 endOffset
broker-0 根據 leader epoch endOffset 進行 truncate:
之后正常生產消息和副本同步:
該過程,如果 acks=-1,則生產消息 c 時,返回客戶端的是生產失敗,不算消息丟失;如果 acks=0 或 1,則消息 c 丟失
5.2 unclean.leader.election.enable=true 引起的數據丟失
還是這個例子,broker-0 為 leader,broker-1 為 follower,各有兩條消息 a、b,此時 broker-1 宕機,isr=[0]
在 broker-1 故障期間,生產消息 c,因為 broker-1 已經不在 isr 中了,所以即使 acks=-1,也能生產成功
然后 broker-0 也宕機,leader=-1,isr=[0]
此時 broker-1 先拉起,若 unclean.leader.election.enable=true,那么即使 broker-1 不在 isr 中,因為 broker-1 是唯一活著的節(jié)點,因此 broker-1 會選舉為 leader,并更新 leaderEpoch 為 2
這時,broker-0 再拉起,會先通過 OFFSET_FOR_LEADER_EPOCH,從 broker-1 獲取 epoch 信息,并進行數據截斷
再進行生產消息和副本同步
消息 c 丟失
以上就是Kafka 網絡中斷和網絡分區(qū)4種場景分析的詳細內容,更多關于Kafka 網絡中斷網絡分區(qū)的資料請關注腳本之家其它相關文章!
相關文章
RestTemplate使用Proxy代理作為跳板發(fā)送請求
這篇文章主要為大家介紹了RestTemplate使用代理proxy作為跳板發(fā)送請求的方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2022-03-03解決java轉義json出現(xiàn)\u0000 等亂碼的問題
這篇文章主要介紹了解決java轉義json出現(xiàn)\u0000 等亂碼的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03關于Java中配置ElasticSearch集群環(huán)境賬號密碼的問題
這篇文章主要介紹了Java中配置ElasticSearch集群環(huán)境賬號密碼的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04