1. 程式人生 > 實用技巧 >一文入門Zookeeper

一文入門Zookeeper

一、什麼是Zookeeper

1.1 概述

在我的印象中,zookeeper是可以作為註冊中心來存在的,之前的微服務架構更多的是採用Dubbo+zookeeper來搭配著使用的,因此,zookeeper它是主要服務於分散式系統。

而分散式系統的特點就是會有多個節點存在,實時感知每個節點的狀態,管理每個節點就變得尤為重要。而zookeeper的出現就解決了這個問題。 從設計模式角度來理解:它是一個基於觀察者模式設計的分散式服務管理框架,它負責儲存管理大家都關心的資料,然後接受觀察者的註冊,一旦這些資料的狀態發生了變化,zookeeper就負責通知已經在zookeeper上註冊的那些觀察者,讓他們做出相應的反應。

因此,zookeeper可以概況為:檔案系統+通知機制

福利 福利 福利 免費領取Java架構技能地圖 注意了是免費送

免費領取 要的+V 領取

工作機制

  • 1、服務端啟動時去註冊資訊(建立的都是臨時節點)
  • 2、獲取到當前線上伺服器列表,並且註冊監聽
  • 3、伺服器節點下線
  • 4、伺服器節點下線事件通知
  • 5、process重新再去獲取伺服器列表,並註冊監聽

1.2 特點

1、Zookeeper是設計模式是由一個領導者和多個跟隨者組成的叢集

2、半數原則:叢集中只要有半數以上的節點存活,zookeeper叢集就能正常服務

3、全域性資料一致,每個server伺服器儲存一份相同的資料副本,client無論連線到哪個server,資料都一致

4、資料更新原子性:一次資料更新要麼成功,要麼失敗。

5、實時性:在一定時間範圍內,client能夠讀到最新資料。

1.3 資料結構

zookeeper的資料模型與linux檔案系統很類似,整體可以看作是一棵樹,每個節點稱為znode,預設能夠儲存1Mb的資料,每個znode都可以通過其路徑唯一標識:

而這些節點可以分為兩類:臨時和持久。因此一個面試題產生了:zookeeper的節點型別有哪些?

  • 臨時普通節點
  • 臨時有序節點
  • 持久普通節點
  • 持久有序節點

1.4 zookeeper能幹啥?

zookeeper 提供的服務包括:統一命名服務,統一配置管理,統一叢集管理,軟負載均衡,分散式鎖。

1.4.1 統一命名服務

可以理解為訪問域名:www.baidu.com 的時候,這個域名下面有很多臺伺服器:192.168.1.100,192.168.1.101,192.168.1.102等。別人只要訪問這個域名,zookeeper就會把請求轉發給註冊過的某個伺服器上。而使用者並不用去記住訪問哪個ip地址,只需要知道這個域名就可以了。

1.4.2 統一配置管理

把公共的配置檔案抽取出來,分發給其他系統。

配置檔案同步非常常見。一般要求一個叢集中,所有的節點的配置資訊是一致的,比如kafka叢集,對配置檔案修改後,希望能夠快速同步到各個配置上。

blog.csdn.net/u011320740/…

1.4.3 統一叢集管理

1)分散式環境中,實時掌握每個節點的狀態是必要的,可根據節點實時狀態進行調整。

2) zookeeper 可以實現實時監控節點狀態變化。

  • 可將節點資訊寫入zookeeper上的一個Znode
  • 監聽這個znode可獲取它的實時狀態變化。

1.4.4 軟負載均衡

再zookeeper中記錄每臺伺服器的訪問數,讓訪問最少的伺服器去處理最新的客戶端請求。

1.4.5 分散式鎖

如果有a、b、c多個客戶端去搶一個zookeeper分散式鎖。原理是這樣的:

  • 剛訪問 /lock 鎖節點的時候,大家都上來直接建立一個接一個的有序節點。例如a系統建立了001節點。b系統建立了002節點,c系統建立了003節點。
  • 系統拿到所有的節點後,會比較自己的節點是不是最小的,如果是,則得到鎖,如果不是,就對上個節點加監聽器,監視它。
  • 只要上一個節點釋放鎖,自己就排到前面去了,相當於一個排隊機制。

用臨時節點 第一個用意:如果某個客戶端建立臨時順序節點之後,不小心自己宕機了也沒關係,zookeeper感知到那個客戶端宕機,會自動刪除對應的臨時順序節點,相當於自動釋放鎖,或者是自動取消自己的排隊。

二、zookeeper安裝

2.1 本地模式安裝部署

1、步驟:

  • 配置修改:conf下的zoo_sample.cfg修改為zoo.cfg
  • 在zookeeper目錄下建立dataDir資料夾,存放資料的儲存目錄。
  • 在zookeeper下面新增資料存放路徑:
dataDir=/opt/module/zookeeper-3.5.7/zkData
複製程式碼
  • 啟動
[root@hadoop101 zookeeper-3.5.7]# bin/zkServer.sh start
複製程式碼
  • 檢視狀態
[root@hadoop101 zookeeper-3.5.7]# bin/zkServer.sh status
複製程式碼
  • 啟動客戶端 連線指定的host的zk服務
[root@hadoop101 zookeeper-3.5.7]# bin/zkCli.sh -server host:port 
複製程式碼
  • 停止
[root@hadoop101 zookeeper-3.5.7]# bin/zkServer.sh stop
複製程式碼

2.2 配置引數解讀

1)tickTime =2000:通訊心跳數,Zookeeper伺服器與客戶端心跳時間,單位毫秒 Zookeeper使用的基本時間,伺服器之間或客戶端與伺服器之間維持心跳的時間間隔,也就是每個tickTime時間就會發送一個心跳,時間單位為毫秒。 它用於心跳機制,並且設定最小的session超時時間為兩倍心跳時間。 (session的最小超時時間是2*tickTime)

2)initLimit =10:LF初始通訊時限 叢集中的Follower跟隨者伺服器與Leader領導者伺服器之間初始連線時能容忍的最多心跳數(tickTime的數量),用它來限定叢集中的Zookeeper伺服器連線到Leader的時限。

3)syncLimit =5:LF同步通訊時限 叢集中Leader與Follower之間的最大響應時間單位,假如響應超過syncLimit * tickTime,Leader認為Follwer死掉,從伺服器列表中刪除Follwer。

4)dataDir:資料檔案目錄+資料持久化路徑 主要用於儲存Zookeeper中的資料。

5)clientPort =2181:客戶端連線埠 監聽客戶端連線的埠

三、Zookeeper內部原理

3.1 節點型別(Znode)

持久:客戶端和伺服器斷開後,建立的節點不刪除。

1)普通持久節點

2)帶序號的持久節點(序號zookeeper自己維護)

短暫:客戶端和伺服器斷開連線後,建立的節點自己刪除。

1)普通短暫節點

2)帶序號的短暫節點(序號zookeeper自己維護)

3.2 Stat結構體

描述每個ZNode的狀態資訊

[zk: localhost:2181(CONNECTED) 12] stat /zookeeper
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -2
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 2
複製程式碼

(1)czxid-建立節點的事務zxid 每次修改ZooKeeper狀態都會收到一個zxid形式的時間戳,也就是ZooKeeper事務ID。 事務ID是ZooKeeper中所有修改總的次序。每個修改都有唯一的zxid,如果zxid1小於zxid2,那麼zxid1在zxid2之前發生。

(2)ctime - znode被建立的毫秒數(從1970年開始)

(3)mzxid - znode最後更新的事務zxid

(4)mtime - znode最後修改的毫秒數(從1970年開始)

(5)pZxid-znode最後更新的子節點zxid

(6)cversion - znode子節點變化號,znode子節點修改次數

(7)dataversion - znode資料變化號

(8)aclVersion - znode訪問控制列表的變化號

(9)ephemeralOwner- 如果是臨時節點,這個是znode擁有者的session id。如果不是臨時節點則是0。

(10)dataLength- znode的資料長度

(11)numChildren - znode子節點數量

3.3 監聽器原理

1、原理

  • 首先要有一個main()執行緒
  • 在main執行緒中建立zookeeper客戶端,這時就會建立兩個執行緒,一個負責網路連線通訊(connect),一個負責監聽(listener)
  • 通過connect執行緒將註冊的監聽事件傳送給zookeeper
  • 在zookeeper的註冊監聽列表中將註冊的監聽事件新增到列表中
  • zookeeper監聽到有資料或路徑變化,就會把這個訊息傳送
  • listener執行緒內部呼叫了process()方法

2、常見的監聽

  • 監聽節點資料的變化:get path
  • 監聽子節點增減的變化:ls path

3.4 選舉機制

3.4.1 ZAB協議:

基於訊息傳遞且保證資料一致性的一種演算法(協議)

協議目標:

1、沒有leader的情況下選舉leader

2、有leader的情況,去儘可能保證資料一致。

3.4.2 zj叢集

(1)半數機制:叢集中半數以上機器存活,叢集可用。所以Zookeeper適合安裝奇數臺伺服器。

(2)Zookeeper 雖然在配置檔案中並沒有指定Master和Slave。但是,Zookeeper工作時,是有一個節點為Leader,其他則為Follower,Leader是通過內部的選舉機制臨時產生的。

3.4.3 機制概念

1、Serverid: 伺服器id 比如有三臺伺服器,編號分別是1,2,3

2、Zxid:資料ID

伺服器中存放的最大資料ID :值越大說明資料越新,在選舉演算法中資料越新權重越大。

3、Epoch:邏輯時鐘

或者叫投票的次數,同一輪投票過程中的邏輯時鐘值是相同的。每投完一次票這個資料就會增加,然後與接收到返回的投票資訊的數值相比,根據不同的值做出不同的判斷。

4、Server狀態:選舉狀態

  • LOOKing:競選
  • FOLLOWING:隨從狀態
  • OBSERVING:觀察狀態,
  • LESDING:領導者狀態。

3.4.4選舉過程

假設有五臺伺服器組成的Zookeeper 叢集,它們的id從1-5 ,同時它們都是最新啟動的,也就是沒有歷史資料,在存放資料量這點上,都是一樣的。

投票原則

  • 自私原則(伺服器剛註冊的時候都會投自己一票)
  • 牆頭草隨風倒原則:(發現有其他伺服器比自己厲害,就投其他伺服器)比較的東西可以為zxid 時間戳,哪個伺服器有最新的資料就投它。

過程

(1)伺服器1啟動,發起一次選舉。伺服器1投自己一票。此時伺服器1票數一票,不夠半數以上(3票),選舉無法完成,伺服器1狀態保持為LOOKING;

(2)伺服器2啟動,再發起一次選舉。伺服器1和2分別投自己一票並交換選票資訊:此時伺服器1發現伺服器2的ID比自己目前投票推舉的(伺服器1)大,更改選票為推舉伺服器2。此時伺服器1票數0票,伺服器2票數2票,沒有半數以上結果,選舉無法完成,伺服器1,2狀態保持LOOKING

(3)伺服器3啟動,發起一次選舉。此時伺服器1和2都會更改選票為伺服器3。此次投票結果:伺服器1為0票,伺服器2為0票,伺服器3為3票。此時伺服器3的票數已經超過半數,伺服器3當選Leader。伺服器1,2更改狀態為FOLLOWING,伺服器3更改狀態為LEADING;

(4)伺服器4啟動,發起一次選舉。此時伺服器1,2,3已經不是LOOKING狀態,不會更改選票資訊。交換選票資訊結果:伺服器3為3票,伺服器4為1票。此時伺服器4服從多數,更改選票資訊為伺服器3,並更改狀態為FOLLOWING;

(5)伺服器5啟動,同4一樣當小弟。

3.4.5 leader故障後選舉

當叢集工作中,leader故障後,只要剩下的機器數大於半數,叢集能夠正常工作,但是需要重新選舉leader。選舉的過程還是進行投票,因為叢集是在工作中,因此每臺機器的id有可能不同。那麼每次投出的票(myid,zxid),先比較zxid,再比較myid,因此叢集中剩餘的機器中zxid最大的當選leader,如果zxid都一樣,理論情況下myid最大的勝出。

zxid 時間戳,最新的資料。某種意義上,可以表示當前機器中儲存的資料完整度。

3.5 寫資料流程

1)客戶端連線zk叢集的任意一臺機器,傳送寫請求

2)如果客戶端連線的zk叢集部署leader,則當前這臺機器會將客戶端的寫請求轉發給leadet

3)當leader接收到寫請求後,會將當次的寫操作構造成一個事務,對應一個zxid

4)每個follower接收到寫操作後,先將寫操作存入佇列中,並向leader反饋

5)當leader接收到叢集中半數以上的follower的反饋,則代表本次寫操作可以正常進行,

leader會再次廣播給各個follower,讓follower將寫操作進行commit(真正寫資料)

四、最後

有關zookeeper的內容還遠不止這些,這篇更多的是介紹一些zookeeper的概念,少許客戶端的命令操作就每放上來了,今天我們知道zookeeper的儲存節點和監聽機制,就可以實現很多功能。目前階段瞭解這些就夠了,有機會再深入的話,會寫後續的文章來介紹。