今天講一講分布式系統中必不可少的選舉算法。
leader 就是一堆服務器中的協調者,某一個時刻只能有一個leader且所有服務器都承認這個leader. leader election就是在一組進程中,選舉一個leader且讓該組的進程都同意這個leader.
假設有N個process, 每個process都有個可以比較的ID,可以提出選舉。
leader election算法要滿足兩點:
- safety: 每一個進程要么不知道結果,要么知道正確的結果(不會選錯leader)。
- liveness: 選舉算法總會結束,每一個進程都知道了結果。
Ring leader election 環算法
processes組成了一個環,第i個 process p_i 可以和 p_(i+1)modN通信。
如果進程i發現原來的leader掛了,它就會發起選舉,發送一個包含自己ID a_i “Election”的信息。然后當某個進程j收到了這個信息的時候,會將這個a_i與自己的ID a_j比,如果a_i>a_j, 繼續轉發這條消息,如果a_i<a_j且它之前沒有轉發過消息,就把a_i取代掉然后把消息發送出去。如果發現收到的標識符和自己的一樣,代表自己成為leader,然后把自己當選的信息發送出去。
最壞情況分析:一個進程發起選舉,如果它的上一個進程具有最大標識符,則選舉消息到達上一個進程需要(N—1)次傳遞,然后消息又要N次才能宣布它當選,最后需要N個消息告訴大家它當選了,所以需要(3N-1)個消息。最好情況就是發起選舉的進程就是leader,只需要(2N)個消息。如果有多個進程同時發起選舉,那么只有具有最大ID的進程會完成選舉。
但是環算法實用價值很少,因為在選舉過程中如果有進程崩潰,選舉就無法完成,不符合liveness的要求。
實際生產中的Leader Election
用Paxos-like (Paxos是解決一致性問題的一種方法) 來選舉。
Google Chubby
A system for locking
每個process最多選舉一次,得到最多選票且大於某一數值的process當選。
Apache Zookeeper
Centralized service for maintaining configuration information
Paxos的變種Zab(Zookeeper Atomic Broadcast)。必須始終保持有leader。
每個進程都向ZK文件系統中寫入自己的ID,只要保證寫入是原子性的,就把最大ID的進程選為leader.
每個進程都監視着正好比自己ID高的進程,如果那個進程是leader然后掛掉了,那么它就成為新的leader.
Bully Algorithm 霸道算法
假設系統是同步的,所有進程都可以互相通信。當某一進程發現leader掛掉,如果自己ID最大,就宣布自己是leader,否則向ID比自己高的進程發起選舉。發起選舉如果沒有收到回應,就宣布自己是leader,收到了回應就等待比自己ID大的進程宣布結果。
當一個進程收到從ID比自己低的進程發來的選舉消息時,就向更高的進程發起選舉。
最壞時間復雜度分析:只需5個消息傳遞時間
- 最小ID進程發起選舉
- 第二大ID進程回應
- 第二大ID進程向最大ID進程發起選舉
- 最大ID進程無回應,timtout
- 第二大ID進程宣布當選
