zookeeper淺談

1、ZooKeeper是什麼?

ZooKeeper 是一個開源的分佈式服務框架Hadoop的一個子項目,Zookeeper 實現諸如數據發佈/訂閱、統一命名服務、分佈式協調/通知、配置管理、分佈式鎖和分佈式隊列等功能,通俗的講zookeeper是一個支持增刪查改的類似文件系統特點的數據庫,按照規則去給節點分配任務。zookeeper底層實現了存儲文件和通知回調功能它的數據結構類似於一個標準的文件系統,相比較文件系統zk的每個節點都可以存儲數據,但是大小限制爲1M。通常我們在使用dubbo的時候會建議使用zookeeper作爲註冊中心,也可以用redis,eureka作爲註冊中心,當然我只用過zookeeper,dubbo相當於搭載一個服務框架,zookeeper則是服務註冊的中心。


zk的數據結構

zk服務的配置文件

上面提到zk就是一個數據庫那麼它的數據就儲存在dataDir中,上圖中的配置是一個集羣配置,有server1,server2,server3三臺服務器,我們這裏是一個僞集羣(同一臺機器啓動三個server),我們可以看到localhost:A:B,其中licalhost是我們的服務ip,A是專門用來選舉的端口,B集羣進行通信端口,clientPort是對client提供服務的端口。

名詞解釋:

數據發佈/訂閱:初始化節點的時候在服務節點註冊一個數據變更Watcher ,對節點進行變更操作的時候會將數據通知到客戶端,客戶端接受到變更通知後會重新讀取變更後的數據。

統一命名服務:獲得全局的唯一名稱,還可以藉助znode順序節點的特性產生的節點都會返回順序編號,在按照給定的名字,生成具有特殊含義的統一名字,所有客戶端可創建同一個名字的不同順序節點。

2、服務器的角色?以及狀態

服務器有Leader、Follower、Observer三種角色 ,其中Leader是集羣內部各個服務的調度者,保證了事務處理的順序性。Follower參與Proposal的投票,參與Leader選舉投票,處理客戶端的非事務請求,轉發事務請求(增刪改,數據變更的操作)給Leader服務器。Observer不參與投票,在不參與集羣事務能力的基礎上提升集羣的非事務處理能力。

服務器的狀態分別爲LOOKING(認爲進羣中服務器沒有Leader尋找Leader的狀態)、FOLLOWING(服務器角色是Follower的狀態)、LEADING(服務器角色是 Leader的狀)、OBSERVING(服務器角色是Observer的狀態)。

領導者選舉發生的節點有Leader掛掉的時候,集羣服務器啓動的時候,Follower掛掉後Leader發現沒有過半的Follower跟隨了,這三種情況會觸發領導者選舉。

3、zookeeper如何解決數據一致性問題?

zookeeper server的啓動過程經歷了什麼。

若要了解zookeepr如何解決數據一致性,zookeeper其實想達到的是強一致性,但是最終達到的是最終一致性,首先我們瞭解下什麼是CAP?這個大家自行百度,ZK遵循的是CP原則,犧牲了可用性,滿足了強一致性。如下圖數據庫A 的數據進行了變更爲2後,在步驟2進行讀取的時候不能讀取到的是1,那麼要求數據庫之間同步非常迅速或者在步驟2上加上鎖待數據同步完成後再讀取到結果.


強一致性的例子

我們來大致跟下源碼中的選舉流程我用的是git上的3.6.1的版本,找到zkServer.sh


找到守護進程的啓動腳本

找到參數中ZOOMAIN="org.apache.zookeeper.server.quorum.QuorumPeerMain"對應的這個類就是你查看源碼服務的入口了。

在入口main方法中有一個初始化方法,main.initializeAndRun(args);這個方法進入以後圖中標紅的是進入集羣模式的方法,我們來看這個方法。


判斷爲集羣模式

進入方法之後你會看到一堆set,讀取配置文件值到QuorumPeer這個對象中呢,然後是對象的start,在啓動的時候就進行了調用選舉方法。

大家想一下zookeeper爲何選擇奇數服務器?

這個要從zookeeper的過半機制說起,假如6臺機器只最大允許集羣中宕掉2臺機器,5 臺機器也是允許宕機兩臺,從資源利用的角度所以建議選擇奇數臺服務器.

標紅的這塊爲//投票決定方式,默認超過半數就通過


標紅的爲leader選舉方法


默認electionAlgorithm爲3

在FastLeaderElection類中lookForLeader方法的case looking 條件下進行投票選舉。private boolean totalOrderPredicate(long newId, long newZxid, long newEpoch, long curId, long curZxid, long curEpoch)將收到的對方的投票與當前自己的投票對比,判斷對方的投票是否優於自己的投票。


totalOrderPredicate

只要當前服務器狀態爲LOOKING,進入循環,不斷地讀取其它Server發來的通知、進行比較、更新自己的投票、發送自己的投票、統計投票結果,直到leader選出或出錯退出。

選舉比重參數

①Serverid:服務器ID比如有三臺服務器,編號分別是1,2,3。編號越大在選擇算法中的權重越大。

②Zxid:事務日誌id,事務請求每次就會生成一條事務日誌,服務器中存放的最大數據ID.值越大說明數據越新,在選舉算法中數據越新權重越大。

③Epoch:邏輯時鐘,或者叫投票的次數,同一輪投票過程中的邏輯時鐘值是相同的。每投完一次票這個數據就會增加,然後與接收到的其它服務器返回的投票信息中的數值相比

集羣啓動投票流程

①每個Server會發出一個投票,因此對於Server1,Server2和Server3來說,都會將自己作爲Leader服務器來進行投票,每次投票包含最基本的元素有:所推舉的服務器的myid和zxid,我們以(myid,zxid)的形式來表示,即Server1的投票爲(1,0),Server2的投票爲(2,0),然後各自將這個投票發給集羣中其他所有機器。

② 接收來自各個服務器的投票,判斷該投票的有效性,包括檢查是否是本輪投票,是否來自LOOKING狀態的服務器。

③ pk投票,在接收到來自其他服務器的投票後,針對每一個投票,服務器都需要將別人的投票和自己的投票進行PK:

  1. 優先檢查zxid,zxid比較大的服務器優先作爲Leader。

  2. 如果zxid相同的話,那麼就比較myid,myid比較大的服務器作爲Leader服務器。結果Server1{(2,0),(2,0)},Server2{(2,0),2,0)}將票投給了Server2,那麼Server3也就直接跟隨投給了Sever2,最終確定了Leader。

作者:宜信技術學院 王巧敏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章