zookeeper淺談

一、ZooKeeper是什麼?

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

zookeeper淺談
zk的數據結構
zookeeper淺談
zk服務的配置文件git

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

名詞解釋:

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

統一命名服務:得到全局的惟一名稱,還能夠藉助znode順序節點的特性產生的節點都會返回順序編號,在按照給定的名字,生成具備特殊含義的統一名字,全部客戶端可建立同一個名字的不一樣順序節點。數據庫

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

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

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

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

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

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

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

zookeeper淺談
強一致性的例子

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

zookeeper淺談
找到守護進程的啓動腳本

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

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

zookeeper淺談
判斷爲集羣模式

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

你們想一下zookeeper爲什麼選擇奇數服務器?

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

zookeeper淺談

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

zookeeper淺談
標紅的爲leader選舉方法

zookeeper淺談
默認electionAlgorithm爲3

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

zookeeper淺談
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。

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

相關文章
相關標籤/搜索