好文推薦:可能是全網把 ZooKeeper 概念講的最清楚的一篇文章

好文推薦:可能是全網把 ZooKeeper 概念講的最清楚的一篇文章

一.ZooKeeper是什麼

Zookeeper 從設計模式角度來看,是一個基於觀察者模式設計的分佈式服務管理框架,它負責存儲和管理大家都關心的數據,然後接受觀察者的註冊,一旦這些數據的狀態發生變化,Zookeeper 就將負責通知已經在 Zookeeper 上註冊的那些觀察者做出相應的反應。

​二.ZooKeeper能解決什麼

1.命名服務(Name service)

  • ZooKeeper提供類似JNDI服務,都能夠幫助應用系統通過一個資源引用的方式來實現對資源的定位與實用。
  • 利用ZooKeeper順序節點的特性,製作分佈式的ID生成器。

2.配置管理

配置的管理在分佈式應用環境中很常見,例如同一個應用系統需要多臺 PC Server 運行,但是它們運行的應用系統的某些配置項是相同的,如果要修改這些相同的配置項,那麼就必須同時修改每臺運行這個應用系統的 PC Server,這樣非常麻煩而且容易出錯。

像這樣的配置信息完全可以交給 Zookeeper 來管理,將配置信息保存在 Zookeeper 的某個目錄節點中,然後將所有需要修改的應用機器監控配置信息的狀態,一旦配置信息發生變化,每臺應用機器就會收到 Zookeeper 的通知,然後從 Zookeeper 獲取新的配置信息應用到系統中

好文推薦:可能是全網把 ZooKeeper 概念講的最清楚的一篇文章

3.集群管理

Zookeeper 能夠很容易的實現集群管理的功能,如有多臺 Server 組成一個服務集群,那麼必須要一個“總管”知道當前集群中每臺機器的服務狀態,一旦有機器不能提供服務,集群中其它機器必須知道,從而做出調整重新分配服務策略。同樣當增加集群的服務能力時,就會增加一臺或多臺 Server,同樣也必須讓“總管”知道。

Zookeeper 不僅能夠幫你維護當前的集群中機器的服務狀態,而且能夠幫你選出一個“總管”,讓這個總管來管理集群,這就是 Zookeeper 的另一個功能 Leader Election。

它們的實現方式都是在 Zookeeper 上創建一個 EPHEMERAL 類型的目錄節點,然後每個 Server 在它們創建目錄節點的父目錄節點上調用 getChildren(String path, boolean watch) 方法並設置 watch 為 true,由於是 EPHEMERAL 目錄節點,當創建它的 Server 死去,這個目錄節點也隨之被刪除,所以 Children 將會變化,這時 getChildren上的 Watch 將會被調用,所以其它 Server 就知道已經有某臺 Server 死去了。新增 Server 也是同樣的原理。

Zookeeper 如何實現 Leader Election,也就是選出一個 Master Server。和前面的一樣每臺 Server 創建一個 EPHEMERAL 目錄節點,不同的是它還是一個 SEQUENTIAL 目錄節點,所以它是個 EPHEMERAL_SEQUENTIAL 目錄節點。之所以它是 EPHEMERAL_SEQUENTIAL 目錄節點,是因為我們可以給每臺 Server 編號,我們可以選擇當前是最小編號的 Server 為 Master,假如這個最小編號的 Server 死去,由於是 EPHEMERAL 節點,死去的 Server 對應的節點也被刪除,所以當前的節點列表中又出現一個最小編號的節點,我們就選擇這個節點為當前 Master。這樣就實現了動態選擇 Master,避免了傳統意義上單 Master 容易出現單點故障的問題

三.Zookeeper的數據模型

Zookeeper 會維護一個具有層次關係的數據結構,它非常類似於一個標準的文件系統

好文推薦:可能是全網把 ZooKeeper 概念講的最清楚的一篇文章

圖片來自於網絡,如有侵權請聯繫作者刪除

每個節點在zookeeper中叫做znode,每個znode節點有唯一的路徑標識,Znode節點分為:臨時節點和持久化節點

臨時節點的生命週期與創建該節點的客戶端的生命週期一致,一旦客戶端與zookeeper服務器失去聯繫,這個節點也將被刪除--臨時節點不能擁有子節點

持久化節點是指與客戶端狀態無關的節點的,除非客戶端主動發起刪除操作,否則就算客戶端與服務器失去聯繫,該節點依然存在

znode 是有版本的,每個 znode 中存儲的數據可以有多個版本,也就是一個訪問路徑中可以存儲多份數據

znode 可以被監控(可以設置Watcher),包括這個目錄節點中存儲的數據的修改,子節點目錄的變化等,一旦變化可以通知設置監控的客戶端,這個是 Zookeeper 的核心特性。

四.Leader選舉

Leader選舉是保證分佈式數據一致性的關鍵所在。當Zookeeper集群中的一臺服務器出現以下兩種情況之一時,需要進入Leader選舉。

(1) 服務器初始化啟動。

(2) 服務器運行期間無法和Leader保持連接

1.服務器啟動時的Leader選舉

若進行Leader選舉,則至少需要兩臺機器,這裡選取3臺機器組成的服務器集群為例。在集群初始化階段,當有一臺服務器Server1啟動時,其單獨無法進行和完成Leader選舉,當第二臺服務器Server2啟動時,此時兩臺機器可以相互通信,每臺機器都試圖找到Leader,於是進入Leader選舉過程。選舉過程如下

(1) 每個Server發出一個投票。由於是初始情況,Server1和Server2都會將自己作為Leader服務器來進行投票,每次投票會包含所推舉的服務器的myid和ZXID,使用(myid, ZXID)來表示,此時Server1的投票為(1, 0),Server2的投票為(2, 0),然後各自將這個投票發給集群中其他機器。

(2) 接受來自各個服務器的投票。集群的每個服務器收到投票後,首先判斷該投票的有效性,如檢查是否是本輪投票、是否來自LOOKING狀態的服務器。

(3) 處理投票。針對每一個投票,服務器都需要將別人的投票和自己的投票進行PK,PK規則如下

· 優先檢查ZXID。ZXID比較大的服務器優先作為Leader。

· 如果ZXID相同,那麼就比較myid。myid較大的服務器作為Leader服務器。

對於Server1而言,它的投票是(1, 0),接收Server2的投票為(2, 0),首先會比較兩者的ZXID,均為0,再比較myid,此時Server2的myid最大,於是更新自己的投票為(2, 0),然後重新投票,對於Server2而言,其無須更新自己的投票,只是再次向集群中所有機器發出上一次投票信息即可。

(4) 統計投票。每次投票後,服務器都會統計投票信息,判斷是否已經有過半機器接受到相同的投票信息,對於Server1、Server2而言,都統計出集群中已經有兩臺機器接受了(2, 0)的投票信息,此時便認為已經選出了Leader。

(5) 改變服務器狀態。一旦確定了Leader,每個服務器就會更新自己的狀態,如果是Follower,那麼就變更為FOLLOWING,如果是Leader,就變更為LEADING。

2.服務器運行時的Leader選舉

在Zookeeper運行期間,Leader與非Leader服務器各司其職,即便當有非Leader服務器宕機或新加入,此時也不會影響Leader,但是一旦Leader服務器掛了,那麼整個集群將暫停對外服務,進入新一輪Leader選舉,其過程和啟動時期的Leader選舉過程基本一致。假設正在運行的有Server1、Server2、Server3三臺服務器,當前Leader是Server2,若某一時刻Leader掛了,此時便開始Leader選舉。選舉過程如下

(1) 變更狀態。Leader掛後,餘下的非Observer服務器都會講自己的服務器狀態變更為LOOKING,然後開始進入Leader選舉過程。

(2) 每個Server會發出一個投票。在運行期間,每個服務器上的ZXID可能不同,此時假定Server1的ZXID為123,Server3的ZXID為122;在第一輪投票中,Server1和Server3都會投自己,產生投票(1, 123),(3, 122),然後各自將投票發送給集群中所有機器。

(3) 接收來自各個服務器的投票。與啟動時過程相同。

(4) 處理投票。與啟動時過程相同,此時,Server1將會成為Leader。

(5) 統計投票。與啟動時過程相同。

(6) 改變服務器的狀態。與啟動時過程相同


分享到:


相關文章: