1. 程式人生 > >zookeeper與kafka的選舉演算法

zookeeper與kafka的選舉演算法

學習kafka的過程中發現了Kafka 的選舉演算法的獨到之處,這裡通過與zk的選舉的對比,回顧一下zk的知識,同時也入門一下kafka的知識。

zookeeper 的選舉演算法:

Phase 0: Leader election(選舉階段)
節點在一開始都處於選舉階段,只要有一個節點得到超半數節點的票數,它就可以當選準 leader。只有到達 Phase 3 準 leader 才會成為真正的 leader。這一階段的目的是就是為了選出一個準 leader,然後進入下一個階段。
協議並沒有規定詳細的選舉演算法,預設使用的 Fast Leader Election。
Phase 1: Discovery(發現階段)
在這個階段,followers 跟準 leader 進行通訊,同步 followers 最近接收的事務提議。這個一階段的主要是三個目的:
1.是發現當前大多數節點接收的最新提議,並且準 leader 生成新的 epoch,讓 followers 接受,更新它們的 acceptedEpoch。
2.當Follower 接受到來自準Leader 的 newEpoch 訊息後,會檢查當前的epoch 是否小於newEpoch,如果是就會重新賦值自己的epoch,並且向leader反饋當前的Follower 的epoch,以及鈣Follower的歷史事務集合。
3.準 leader 接受到來自過半Follower的確認訊息ack之後,準leader 就會從這些過半的伺服器中選取一個Follower 集合,並使用該集合作為初始化集合,這個集合滿足的最大epoch 與 zxid 都是所有集合中最大的(這一步驟最重要,用於同步階段使用,同時也是zookeeper 的 leader掛機以後,新任leader 不會丟失事務的保證,也是ZAB演算法與paxos演算法的不同之處)
這裡寫圖片描述


Phase 2: Synchronization(同步階段)
同步階段主要是利用 leader 前一階段獲得的最新提議歷史,同步叢集中所有的副本。只有當 quorum 都同步完成,準 leader 才會成為真正的 leader。follower 只會接收 zxid 比自己的 lastZxid 大的提議。

zk的選舉演算法大概總結起來為以上幾步,後續的廣播階段與選舉無關,暫不提及。zk的選舉演算法之所以設計成以上幾步,主要是為了保證分散式一致性。當leader階段掛掉之後,新的leader會確保存在過半的Follower 已經提交了之前的leader 週期中的所有事務,發現階段的引入,能夠有效的保證 leader 在新的週期中提出事務之前,所有的程序都已經完成了對之前所有事務的提交。

**

kafka 選舉演算法

**:
Kafka的核心是日誌檔案,日誌檔案在叢集中的同步是分散式資料系統最基礎的要素。
一旦leader down掉了,需要在followers中選擇一個新的leader.但是followers本身有可能延時太久或者crash,所以必須選擇高質量的follower作為leader。必須保證,一旦一個訊息被提交了,但是leader down掉了,新選出的leader必須可以提供這條訊息。大部分的分散式系統採用了多數投票法則選擇新的leader,對於多數投票法則,就是根據所有副本節點的狀況動態的選擇最適合的作為leader。Kafka並不是使用這種方法。
Kafaka動態維護了一個同步狀態的副本的集合(a set of in-sync replicas),簡稱ISR,在這個集合中的節點都是和leader保持高度一致的,任何一條訊息必須被這個集合中的每個節點讀取並追加到日誌中了,才回通知外部這個訊息已經被提交了。因此這個集合中的任何一個節點隨時都可以被選為leader。ISR在ZooKeeper中維護。ISR中有f+1個節點,就可以允許在f個節點down掉的情況下不會丟失訊息並正常提供服。ISR的成員是動態的,如果一個節點被淘汰了,當它重新達到“同步中”的狀態時,他可以重新加入ISR。因此如果leader宕了,直接從ISR中選擇一個follower就行。
那麼如果所有節點都down掉了怎麼辦?Kafka對於資料不會丟失的保證,是基於至少一個節點是存活的,一旦所有節點都down了,這個就不能保證了。
實際應用中,當所有的副本都down掉時,必須及時作出反應。可以有以下兩種選擇:
等待ISR中的任何一個節點恢復並擔任leader。
選擇所有節點中(不只是ISR)第一個恢復的節點作為leader。
這是一個在可用性和連續性之間的權衡。如果等待ISR中的節點恢復,一旦ISR中的節點起不起來或者資料都是了,那叢集就永遠恢復不了了。如果等待ISR意外的節點恢復,這個節點的資料就會被作為線上資料,有可能和真實的資料有所出入,因為有些資料它可能還沒同步到。
Kafka目前選擇了第二種策略,在未來的版本中將使這個策略的選擇可配置,可以根據場景靈活的選擇。
這種窘境不只Kafka會遇到,幾乎所有的分散式資料系統都會遇到。
以上僅僅以一個topic一個分割槽為例子進行了討論,但實際上一個Kafka將會管理成千上萬的topic分割槽.Kafka儘量的使所有分割槽均勻的分佈到叢集所有的節點上而不是集中在某些節點上,另外主從關係也儘量均衡這樣每個幾點都會擔任一定比例的分割槽的leader。
優化leader的選擇過程也是很重要的,它決定了系統發生故障時的空窗期有多久。Kafka選擇一個節點作為“controller”,當發現有節點down掉的時候它負責在游泳分割槽的所有節點中選擇新的leader,這使得Kafka可以批量的高效的管理所有分割槽節點的主從關係。如果controller down掉了,活著的節點中的一個會備切換為新的controller。