4種Kafka網路中斷和網路分割槽場景分析

華為雲開發者聯盟發表於2022-07-08
摘要:本文主要帶來4種Kafka網路中斷和網路分割槽場景分析。

本文分享自華為雲社群《Kafka網路中斷和網路分割槽場景分析》,作者: 中介軟體小哥。

以Kafka 2.7.1版本為例,依賴zk方式部署

3個broker分佈在3個az,3個zk(和broker合部),單分割槽3副本

4種Kafka網路中斷和網路分割槽場景分析

1. 單個broker節點和leader節點網路中斷

網路中斷前:

4種Kafka網路中斷和網路分割槽場景分析

broker-1和broker-0(leader)間的網路中斷後,單邊中斷,zk可用(zk-1為leader,zk-0和zk-2為follower,zk-0會不可用,但zk叢集可用,過程中可能會引起原本連在zk-0上的broker節點會先和zk斷開,再重新連線其他zk節點,進而引起controller切換、leader選舉等,此次分析暫不考慮這種情況),leader、isr、controller都不變

4種Kafka網路中斷和網路分割槽場景分析

az2內的客戶端無法生產消費(metadata指明leader為broker-0,而az2連不上broker-0),az1/3內的客戶端可以生產消費,若acks=-1,retries=1,則生產訊息會失敗,error_code=7(REQUEST_TIMED_OUT)(因為broker-1在isr中,但無法同步資料),且會發兩次(因為retries=1),broker-0和broker-2中會各有兩條重複的訊息,而broker-1中沒有;由於broker-0沒有同步資料,因此會從isr中被剔除,controller同步metadata和leaderAndIsr,isr更新為[2,0]

4種Kafka網路中斷和網路分割槽場景分析

網路恢復後,資料同步,更新isr

2. 單個broker節點和controller節點網路中斷

broker和controller斷連,不影響生產消費,也不會出現資料不一致的情況

4種Kafka網路中斷和網路分割槽場景分析

而當發生leader和isr變化時,controller無法將leader和isr的變化更新給broker,導致後設資料不一致

4種Kafka網路中斷和網路分割槽場景分析

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節點所在az被隔離(分割槽)

4種Kafka網路中斷和網路分割槽場景分析

zk-0和zk-1、zk-2不通,少於半數,az1內zk不可用,broker-0無法訪問zk,不會發生controller選舉,controller還是在broker-1

網路恢復後,broker-0加入叢集,並同步資料

3.1 三副本partition(replicas:[1,0,2]),原leader在broker-1(或broker-2)

4種Kafka網路中斷和網路分割槽場景分析

az1內:

broker-0無法訪問zk,感知不到節點變化,metadata不更新(leader:1,isr:[1,0,2]),依然認為自己是follower,leader在1;az1內的客戶端無法生產消費

az2/3內:

zk可用,感知到broker-0下線,metadata更新,且不發生leader切換(isr:[1,0,2] -> [1,2],leader:1);az2和az3內的客戶端可正常生產消費

3.2 三副本partition(replicas:[0,1,2]),原leader在broker-0

4種Kafka網路中斷和網路分割槽場景分析

az1內:

zk-0和zk-1、zk-2連線中斷,少於一半,az1內zk叢集不可用,Broker-0連不上zk,無法感知節點變化,且無法更新isr,metadata不變,leader和isr都不變;az1內客戶端可以繼續向broker-0生產消費

az2/3內:

zk-1和zk-2連通,zk可用,叢集感知到broker-0下線,觸發leader切換,broker-1成為新的leader(時間取決於 zookeeper.session.timeout.ms),並更新isr;az2/3內的客戶端可以向broker-1生產消費

此時,該分割槽出現了雙主現象,replica-0和replica-1均為leader,均可以進行生產消費

若兩個隔離域內的客戶端都生產了訊息,就會出現資料不一致的情況

示例:(假設網路隔離前有兩條訊息,leaderEpoch=0)

網路隔離前:

4種Kafka網路中斷和網路分割槽場景分析

az1隔離後,分割槽雙主,az1內的客戶端寫入3條訊息:c、d、e,az2/3內的客戶端寫入2條訊息:f、g:

4種Kafka網路中斷和網路分割槽場景分析

這裡leaderEpoch增加2,是因為有兩次增加leaderEpoch的操作:一次是PartitionStateMachine的handleStateChanges to OnlinePartition時的leader選舉,一次是ReplicationStateMachine 的 handleStateChanges to OfflineReplica 時的removeReplicasFromIsr

網路恢復後:

4種Kafka網路中斷和網路分割槽場景分析

由於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保持一致

4種Kafka網路中斷和網路分割槽場景分析

待資料同步後,加入isr,並更新isr為[1,2,0]。之後在觸發preferredLeaderElection時,broker-0再次成為leader,並增加leaderEpoch為3

在網路隔離時,若az1內的客戶端acks=-1,retries=3,會發現生產訊息失敗,而資料目錄中有訊息,且為生產訊息數的4倍(每條訊息重複4次)

4種Kafka網路中斷和網路分割槽場景分析

有前面所述可知,網路恢復後,offset2-13的訊息會被覆蓋,但因為這些訊息在生產時,acks=-1,給客戶端返回的是生產失敗的,因此也不算訊息丟失

因此,考慮此種情況,建議客戶端acks=-1

4. Controller節點所在az被隔離(分割槽)

4.1 Leader節點未被隔離

4種Kafka網路中斷和網路分割槽場景分析

網路中斷後,az3的zk不可用,broker-2(原controller)從zk叢集斷開,broker-0和broker-1重新競選controller

4種Kafka網路中斷和網路分割槽場景分析

最終broker-0選舉為controller,而broker-2也認為自己是controller,出現controller雙主,同時因連不上zk,metadata無法更新,az3內的客戶端無法生產消費,az1/2內的客戶端可以正常生產消費

4種Kafka網路中斷和網路分割槽場景分析

故障恢復後,broker-2感知到zk連線狀態發生變化,會先resign,再嘗試競選controller,發現broker-0已經是controller了,放棄競選controller,同時,broker-0會感知到broker-2上線,會同步LeaderAndIsr和metadata到broker-2,並在broker-2同步資料後加入isr

4種Kafka網路中斷和網路分割槽場景分析

4.2 Leader節點和controller為同一節點,一起被隔離

隔離前,controller和leader都在broker-0:

4種Kafka網路中斷和網路分割槽場景分析

隔離後,az1網路隔離,zk不可用,broker-2競選為controller,出現controller雙主,同時replica-2成為leader,分割槽也出現雙主

4種Kafka網路中斷和網路分割槽場景分析

此時的場景和3.2類似,此時生產訊息,可能出現資料不一致

4種Kafka網路中斷和網路分割槽場景分析

網路恢復後的情況,也和3.2類似,broker-2為controller和leader,broker-0根據leaderEpoch進行truncate,從broker-2同步資料

4種Kafka網路中斷和網路分割槽場景分析

加入isr,然後通過preferredLeaderElection再次成為leader,leaderEpoch加1

5. 補充:故障場景引起資料不一致

5.1 資料同步瞬間故障

初始時,broker-0為leader,broker-1為follower,各有兩條訊息a、b:

4種Kafka網路中斷和網路分割槽場景分析

leader寫入一條訊息c,還沒來得及同步到follower,兩個broker都故障了(如下電):

4種Kafka網路中斷和網路分割槽場景分析

之後broker-1先啟動,成為leader(0和1都在isr中,無論unclean.leader.election.enable是否為true,都能升主),並遞增leaderEpoch:

4種Kafka網路中斷和網路分割槽場景分析

然後broker-0啟動,此時為follower,通過OFFSET_FOR_LEADER_EPOCH從broker-1獲取leaderEpoch=0的endOffset

4種Kafka網路中斷和網路分割槽場景分析

broker-0根據leader epoch endOffset進行truncate:

4種Kafka網路中斷和網路分割槽場景分析

之後正常生產訊息和副本同步:

4種Kafka網路中斷和網路分割槽場景分析

該過程,如果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]

4種Kafka網路中斷和網路分割槽場景分析

在broker-1故障期間,生產訊息c,因為broker-1已經不在isr中了,所以即使acks=-1,也能生產成功

4種Kafka網路中斷和網路分割槽場景分析

然後broker-0也當機,leader=-1,isr=[0]

4種Kafka網路中斷和網路分割槽場景分析

此時broker-1先拉起,若 unclean.leader.election.enable=true,那麼即使broker-1不在isr中,因為broker-1是唯一活著的節點,因此broker-1會選舉為leader,並更新leaderEpoch為2

4種Kafka網路中斷和網路分割槽場景分析

這時,broker-0再拉起,會先通過 OFFSET_FOR_LEADER_EPOCH,從broker-1獲取epoch資訊,並進行資料截斷

4種Kafka網路中斷和網路分割槽場景分析

再進行生產訊息和副本同步

4種Kafka網路中斷和網路分割槽場景分析

訊息c丟失

 

點選關注,第一時間瞭解華為雲新鮮技術~

相關文章