白話之Zookeeper

Zookeeper 是一個分佈式協調服務,可用於服務發現,分佈式鎖,分佈式領導選舉,配置管理等。Zookeeper 提供了一個類似於 Linux 文件系統的樹形結構(可認爲是輕量級的內存文件系統,但只適合存少量信息,完全不適合存儲大量文件或者大文件),同時提供了對於每個節點的監控與通知機制。
 

1、Zookeeper 角色

Zookeeper 集羣是一個基於主從複製的高可用集羣,每個服務器承擔如下三種角色中的一種。

Leader

1. 一個 Zookeeper 集羣同一時間只會有一個實際工作的 Leader,它會發起並維護與各 Follwer及 Observer 間的心跳。

2. 所有的寫操作必須要通過 Leader 完成再由 Leader 將寫操作廣播給其它服務器只要有超過半數節點(不包括 observeer 節點)寫入成功,該寫請求就會被提交(類 2PC 協議)。

 
Follower
1. 一個 Zookeeper 集羣可能同時存在多個 Follower,它會響應 Leader 的心跳。
2. Follower 可直接處理並返回客戶端的讀請求,同時會將寫請求轉發給 Leader 處理。
3. 並且負責在 Leader 處理寫請求時對請求進行投票
 
Observer
角色與 Follower 類似,但是無投票權。Zookeeper 需保證高可用和強一致性,爲了支持更多的客戶端,需要增加更多 Server;Server 增多,投票階段延遲增大,影響性能引入 Observer,Observer 不參與投票; Observers 接受客戶端的連接,並將寫請求轉發給 leader 節點; 加入更多 Observer 節點,提高伸縮性,同時不影響吞吐率。
 

2、ZAB 協議

事務編號 Zxid(事務請求計數器+ epoch
在 ZAB ( ZooKeeper Atomic Broadcast , ZooKeeper 原子消息廣播協議) 協議的事務編號 Zxid設計中,Zxid 是一個 64 位的數字,其中低 32 位是一個簡單的單調遞增的計數器,針對客戶端每一個事務請求,計數器加 1;而高 32 位則代表 Leader 週期 epoch 的編號,每個當選產生一個新的 Leader 服務器,就會從這個 Leader 服務器上取出其本地日誌中最大事務的 ZXID,並從中讀取epoch 值,然後加 1,以此作爲新的 epoch,並將低 32 位從 0 開始計數。
Zxid(Transaction id)類似於 RDBMS 中的事務 ID,用於標識一次更新操作的 Proposal(提議)ID。爲了保證順序性,該 zkid 必須單調遞增。
epoch
epoch:可以理解爲當前集羣所處的年代或者週期,每個 leader 就像皇帝,都有自己的年號,所以每次改朝換代,leader 變更之後,都會在前一個年代的基礎上加 1。這樣就算舊的 leader 崩潰恢復之後,也沒有人聽他的了,因爲 follower 只聽從當前年代的 leader 的命令
Zab 協議有兩種模式:恢復模式(選主)、廣播模式(同步)
Zab 協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步)。當服務啓動或者在領導者崩潰後,Zab 就進入了恢復模式,當領導者被選舉出來,且大多數 Server 完成了和 leader 的狀態同步以後,恢復模式就結束了。狀態同步保證了 leader 和 Server 具有相同的系統狀態。
ZAB 協議 4 階段
Leader election(選舉階段:選出準 Leader
1. Leader election(選舉階段):節點在一開始都處於選舉階段,只要有一個節點得到超半數節點的票數,它就可以當選準 leader。只有到達 廣播階段(broadcast) 準 leader 纔會成爲真正的 leader。這一階段的目的是就是爲了選出一個準 leader,然後進入下一個階段。
 
Discovery(發現階段:接受提議、生成 epoch、接受 epoch
2. Discovery(發現階段):在這個階段,followers 跟準 leader 進行通信,同步 followers最近接收的事務提議。這個一階段的主要目的是發現當前大多數節點接收的最新提議,並且準 leader 生成新的 epoch,讓 followers 接受,更新它們的 accepted Epoch
一個 follower 只會連接一個 leader,如果有一個節點 f 認爲另一個 follower p 是 leader,f在嘗試連接 p 時會被拒絕,f 被拒絕之後,就會進入重新選舉階段
 
Synchronization(同步階段:同步 follower 副本)
3. Synchronization(同步階段):同步階段主要是利用 leader 前一階段獲得的最新提議歷史,同步集羣中所有的副本只有當 大多數節點都同步完成,準 leader 纔會成爲真正的 leader。follower 只會接收 zxid 比自己的 lastZxid 大的提議。
 
Broadcast(廣播階段:leader 消息廣播)
4. Broadcast(廣播階段):到了這個階段,Zookeeper 集羣才能正式對外提供事務服務,並且 leader 可以進行消息廣播。同時如果有新的節點加入,還需要對新節點進行同步。ZAB 提交事務並不像 2PC 一樣需要全部 follower 都 ACK,只需要得到超過半數的節點的 ACK 就可以了。
ZAB 協議 JAVA 實現(FLE:發現階段和同步合併爲 Recovery Phase(恢復階段)
協議的 Java 版本實現跟上面的定義有些不同,選舉階段使用的是 Fast Leader Election(FLE),它包含了 選舉的發現職責。因爲 FLE 會選舉擁有最新提議歷史的節點作爲 leader,這樣就省去了發現最新提議的步驟。實際的實現將 發現階段 和 同步合併爲 Recovery Phase(恢復階段)。所以,ZAB 的實現只有三個階段:Fast Leader Election;Recovery Phase;Broadcast Phase。
 
投票機制
每個 sever 首先給自己投票然後用自己的選票和其他 sever 選票對比,權重大的勝出,使用權重較大的更新自身選票箱。具體選舉過程如下:
1. 每個 Server 啓動以後都詢問其它的 Server 它要投票給誰。對於其他 server 的詢問,server 每次根據自己的狀態都回復自己推薦的 leader 的 id 和上一次處理事務的 zxid(系統啓動時每個 server 都會推薦自己)。
2. 收到所有 Server 回覆以後,就計算出 zxid 最大的那個 Server,並將這個 Server 相關信息設置成下一次要投票的 Server。
3. 計算這過程中獲得票數最多的的 sever 爲獲勝者,如果獲勝者的票數超過半數,則該server 被選爲 leader。否則,繼續這個過程,直到 leader 被選舉出來。
4. leader 就會開始等待 server 連接。
5. Follower 連接 leader,將最大的 zxid 發送給 leader。
6. Leader 根據 follower 的 zxid 確定同步點,至此選舉階段完成。
7. 選舉階段完成 Leader 同步後通知 follower 已經成爲 uptodate 狀態。
8. Follower 收到 uptodate 消息後,又可以重新接受 client 的請求進行服務了。
 
目前有 5 臺服務器,每臺服務器均沒有數據,它們的編號分別是 1,2,3,4,5,按編號依次啓動,它們的選擇舉過程如下:
1. 服務器 1 啓動,給自己投票,然後發投票信息,由於其它機器還沒有啓動所以它收不到反饋信息,服務器 1 的狀態一直屬於 Looking。
2. 服務器 2 啓動,給自己投票,同時與之前啓動的服務器 1 交換結果,由於服務器 2 的編號大所以服務器 2 勝出,但此時投票數沒有大於半數,所以兩個服務器的狀態依然是LOOKING。
3. 服務器 3 啓動,給自己投票,同時與之前啓動的服務器 1,2 交換信息,由於服務器 3 的編號最大所以服務器 3 勝出,此時投票數正好大於半數,所以服務器 3 成爲領導者,服務器1,2 成爲小弟。
4. 服務器 4 啓動,給自己投票,同時與之前啓動的服務器 1,2,3 交換信息,儘管服務器 4 的編號大,但之前服務器 3 已經勝出,所以服務器 4 只能成爲小弟。
5. 服務器 5 啓動,後面的邏輯同服務器 4 成爲小弟。
 

3、Zookeeper 工作原理(原子廣播)

1. Zookeeper 的核心是原子廣播,這個機制保證了各個 server 之間的同步。實現這個機制的協議叫做 Zab 協議。Zab 協議有兩種模式,它們分別是恢復模式和廣播模式。
2. 當服務啓動或者在領導者崩潰後,Zab 就進入了恢復模式,當領導者被選舉出來,且大多數 server 的完成了和 leader 的狀態同步以後,恢復模式就結束了。
3. 狀態同步保證了 leader 和 server 具有相同的系統狀態
4. 旦 leader 已經和多數的 follower 進行了狀態同步後,他就可以開始廣播消息了,即進入廣播狀態。這時候當一個 server 加入 zookeeper 服務中,它會在恢復模式下啓動,發現 leader,並和 leader 進行狀態同步。待到同步結束,它也參與消息廣播。Zookeeper服務一直維持在 Broadcast 狀態,直到 leader 崩潰了或者 leader 失去了大部分的followers 支持。
5. 廣播模式需要保證 proposal 被按順序處理,因此 zk 採用了遞增的事務 id 號(zxid)來保證。所有的提議(proposal)都在被提出的時候加上了 zxid。
6. 實現中 zxid 是一個 64 爲的數字,它高 32 位是 epoch 用來標識 leader 關係是否改變,每次一個 leader 被選出來,它都會有一個新的 epoch。低 32 位是個遞增計數。
7. 當 leader 崩潰或者 leader 失去大多數的 follower,這時候 zk 進入恢復模式,恢復模式需要重新選舉出一個新的 leader,讓所有的 server 都恢復到一個正確的狀態。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章