1.zookeeper是什么?
zookeeper是應用於集群或者節點組中的一種分布式協調服務,管理集群中的各個節點,並通過穩健的同步技術維護共享數據。
2.zookeeper基本概念介紹
2.1 zookeeper中的角色
(a)leader:負責進行投票的發起和決議,更新系統狀態。
(b)follower:用於接受客戶端請求並想客戶端返回結果,在選主過程中參與投票。
(c)observer可以接受客戶端連接,將寫請求轉發給leader,但observer不參加投票過程,只同步leader的狀態,observer的目的是為了擴展系統,提高讀取速度。
2.2 zookeeper中的節點
Znode被分為持久(persistent)節點,順序(sequential)節點和臨時(ephemeral)節點。
(a)持久節點:zookeeper與在創建該特定znode的客戶端斷開連接后,持久節點仍然存在。
(b)臨時節點:客戶端活躍時,臨時節點就是有效的。當客戶端與ZooKeeper集合斷開連接時,臨時節點會自動刪除。
(c)順序節點: 順序節點可以是持久的或臨時的。
3.zookeeper工作原理
3.1 zookeeper工作原理
zookeeper的核心是原子廣播,這個機制保證了各個Server之間的同步。實現這個機制的協議叫做Zab協議。Zab協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步)。當服務啟動或者在領導者崩潰后,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和 leader的狀態同步以后,恢復模式就結束了,進入了廣播模式。每個Server在工作過程中有三種狀態:
(a)LOOKING:當前Server不知道leader是誰,正在搜尋。
(b)LEADING:當前Server即為選舉出來的leader。
(c)FOLLOWING:leader已經選舉出來,當前Server與之同步。
3.2 zookeeper選主流程
當leader崩潰或者leader失去大多數的follower,這時候zk進入恢復模式,恢復模式需要重新選舉出一個新的leader,讓所有的Server都恢復到一個正確的狀態。Zk的選舉算法有兩種:一種是基於basic paxos實現的,另外一種是基於fast paxos算法實現的。系統默認的選舉算法為fast paxos。
(a)基於basic paxos的選主流程:
- 選舉線程由當前Server發起選舉的線程擔任,其主要功能是對投票結果進行統計,並選出推薦的Server;
- 選舉線程首先向所有Server發起一次詢問(包括自己);
- 選舉線程收到回復后,驗證是否是自己發起的詢問(驗證zxid是否一致),然后獲取對方的id(myid),並存儲到當前詢問對象列表中,最后獲取對方提議的leader相關信息(id,zxid),並將這些信息存儲到當次選舉的投票記錄表中;
- 收到所有Server回復以后,就計算出zxid最大的那個Server,並將這個Server相關信息設置成下一次要投票的Server;
- 線程將當前zxid最大的Server設置為當前Server要推薦的Leader,如果此時獲勝的Server獲得n/2 + 1的Server票數,設置當前推薦的leader為獲勝的Server,將根據獲勝的Server相關信息設置自己的狀態,否則,繼續這個過程,直到leader被選舉出來。
(b)基於fast paxos的選主流程:在選舉過程中,某Server首先向所有Server提議自己要成為leader,當其它Server收到提議以后,解決epoch和 zxid的沖突,並接受對方的提議,然后向對方發送接受提議完成的消息,重復這個流程,最后一定能選舉出Leader。
3.3 zookeeper同步流程
選完Leader以后,zk就進入狀態同步過程。
- Leader等待server連接;
- Follower連接leader,將最大的zxid發送給leader;
- Leader根據follower的zxid確定同步點;
- 完成同步后通知follower 已經成為uptodate狀態;
- Follower收到uptodate消息后,又可以重新接受client的請求進行服務了。
3.4 zookeeper讀寫流程
一旦ZooKeeper集合啟動,它將等待客戶端連接。客戶端將連接到ZooKeeper集合中的一個節點。它可以是leader或follower節點。一旦客戶端被連接,節點將向特定客戶端分配會話ID並向該客戶端發送確認。如果客戶端沒有收到確認,它將嘗試連接ZooKeeper集合中的另一個節點。 一旦連接到節點,客戶端將以有規律的間隔向節點發送心跳,以確保連接不會丟失。
-
如果客戶端想要讀取特定的znode,它將會向具有znode路徑的節點發送讀取請求,並且節點通過從其自己的數據庫獲取來返回所請求的znode。為此,在ZooKeeper集合中讀取速度很快。
-
如果客戶端想要將數據存儲在ZooKeeper集合中,則會將znode路徑和數據發送到服務器。連接的服務器將該請求轉發給leader,然后leader將向所有的follower重新發出寫入請求。如果只有大部分節點成功響應,而寫入請求成功,則成功返回代碼將被發送到客戶端。 否則,寫入請求失敗。絕大多數節點被稱為 Quorum 。
組件 | 描述 |
寫入 | 寫入過程由leader節點處理。leader將寫入請求轉發到所有其它follower,並等待follower的回復。如果一半的follower回復,則寫入過程完成。 |
讀取 | 讀取由特定連接的follower/observer在內部執行,因此不需要與集群進行交互。 |
復制數據庫 | 它用於在zookeeper中存儲數據。每個節點都有自己的數據庫,每個節點在一致性的幫助下每次都有相同的數據。 |
Leader | Leader是負責處理寫入請求的節點 |
Follower | follower從客戶端接收寫入請求,並將它們轉發到leader 節點 |
請求處理器 | 只存在於leader節點。它管理來自follower節點的寫入請求 |
原子廣播 | 負責廣播從leader節點到follower節點的變化。 |
3.5 zookeeper的負載均衡算法有哪些?
- 輪詢:將請求按照順序分發到每台服務器上,當其中一台服務器出現故障時,就不參加下一次的輪詢,直至恢復正常。
- 比率:給每台服務器分配一個加權值為比例,根據比例來分配請求。
- 優先權:給所有的服務器分組,然后給每個組設置優先權,所有的請求先分配到優先權最高的服務器組,當該組出現故障后,請求再分配都次級優先權高的服務器組。
- 最少連接數:將請求分配到連接數最少的服務器
- 最快響應時間:將請求分配到響應時間最快的服務器
4.zookeeper的作用
(a)命名服務:zookeeper內部同一目錄下只有唯一一個文件名,所以創建一個目錄,既有唯一的path。
(b)配置管理:如果應用程序部署在多台機器上,那么應用程序的相關配置就需要在這些機器上逐個的去單獨配置。但是如果把這些配置放到zookeeper中的某個節點中,然后讓這些應用程序監聽這個節點,當節點中的配置信息發生變化時,每個應用程序就會收到zookeeper的通知,然后將最新的配置信息更新到系統中。
(c)集群管理:集群管理涉及兩個方面 是否有機器加入或者退出,選舉master。對於機器加入或者退出,因為所有的機器在zookeeper中的某個目錄(我們假設為FatherNode)下都會創建一個臨時子節點(ClientNode1,ClientNode2。。。),然后監聽父目錄FatherNode下所有子節點的變化信息,一旦機器掛掉,則與zookeeper斷開連接,那么該機器對應的臨時子節點也會被刪除,同時其他兄弟節點都會收到通知:該機器掛掉,退出集群了。對於新機器加入,也是類似原理。對於選舉master,當原來的master掛掉后,需要從其他節點中重新選舉出一個新的master,選舉的方式可以是 每次選取編號最小的機器作為master就好,當然也可以通過其他方式。
(d)分布式鎖:使用zookeeper提供分布式鎖有兩種 保持獨占和控制時序。對於保持獨占,就是把zookeeper中的一個znode當做一把鎖,比如所有的客戶端都去創建/lock_updateGoods節點,創建成功的客戶端就獲取了鎖。當釋放鎖時,就刪除/lock_upateGoods節點就行。對於控制時序, /lock_upateGoods目錄已經存在,所有客戶端在它下面創建臨時順序編號目錄節點,和選master一樣,編號最小的獲得鎖,用完刪除該臨時目錄節點。
(e)隊列管理:有兩種類型隊列 ,一種是當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達。對於這一種隊列,在約定目錄下創建臨時目錄節點,監聽節點數目是否是我們要求的數目。另外一種是按照FIFO的方式入隊和出隊,入隊出隊根據編號。
5.思考幾個問題
5.1 為什么zookeeper集群的數目,一般為奇數個?
答:Leader選舉算法采用了Paxos協議,而該協議的核心思想是:超過半數的server寫成功,即表示寫成功。比如三台服務器和四台服務器都是最多只能有一台服務器掛掉,它們的容災能力都是一樣的,所以為了節省服務器資源,一般我們采用奇數個數,作為服務器部署個數。