Zookeeper快速入門

Zookeeper 概述

ZooKeeper是一種分佈式協調服務,用於管理大型主機。在分佈式環境中協調和管理服務是一個複雜的過程。ZooKeeper經過其簡單的架構和API解決了這個問題。ZooKeeper容許開發人員專一於核心應用程序邏輯,而沒必要擔憂應用程序的分佈式特性。node

分佈式應用的優勢算法

  • 可靠性 - 單個或幾個系統的故障不會使整個系統出現故障。
  • 可擴展性 - 能夠在須要時增長性能,經過添加更多機器,在應用程序配置中進行微小的更改,而不會有停機時間。
  • 透明性 - 隱藏系統的複雜性,並將其顯示爲單個實體/應用程序。

分佈式應用的挑戰數據庫

  • 競爭條件 - 兩個或多個機器嘗試執行特定任務,實際上只需在任意給定時間由單個機器完成。例如,共享資源只能在任意給定時間由單個機器修改。
  • 死鎖 - 兩個或多個操做等待彼此無限期完成。
  • 不一致 - 數據的部分失敗。

什麼是Apache ZooKeeper?

Apache ZooKeeper是由集羣(節點組)使用的一種服務,用於在自身之間協調,並經過穩健的同步技術維護共享數據。ZooKeeper自己是一個分佈式應用程序,爲寫入分佈式應用程序提供服務。apache

ZooKeeper提供的常見服務以下 :vim

  • 命名服務 - 按名稱標識集羣中的節點。它相似於DNS,但僅對於節點。
  • 配置管理 - 加入節點的最近的和最新的系統配置信息。
  • 集羣管理 - 實時地在集羣和節點狀態中加入/離開節點。
  • 選舉算法 - 選舉一個節點做爲協調目的的leader。
  • 鎖定和同步服務 - 在修改數據的同時鎖定數據。此機制可幫助你在鏈接其餘分佈式應用程序(如Apache HBase)時進行自動故障恢復。
  • 高度可靠的數據註冊表 - 即便在一個或幾個節點關閉時也能夠得到數據。

ZooKeeper的好處

  • 簡單的分佈式協調過程
  • 同步 - 服務器進程之間的相互排斥和協做。此過程有助於Apache HBase進行配置管理。
  • 有序的消息
  • 序列化 - 根據特定規則對數據進行編碼。確保應用程序運行一致。這種方法能夠在MapReduce中用來協調隊列以執行運行的線程。
  • 可靠性
  • 原子性 - 數據轉移徹底成功或徹底失敗,但沒有事務是部分的。

ZooKeeper的架構

輸入圖片說明
屏幕截圖.png

Client(客戶端)bash

  • 客戶端,咱們的分佈式應用集羣中的一個節點,從服務器訪問信息。對於特定的時間間隔,每一個客戶端向服務器發送消息以使服務器知道客戶端是活躍的。相似地,當客戶端鏈接時,服務器發送確認碼。若是鏈接的服務器沒有響應,客戶端會自動將消息重定向到另外一個服務器。

Server(服務器)服務器

  • 服務器,咱們的ZooKeeper整體中的一個節點,爲客戶端提供全部的服務。向客戶端發送確認碼以告知服務器是活躍的。

Ensemble架構

  • ZooKeeper服務器組。造成ensemble所需的最小節點數爲3。

Leader:app

  • 服務器節點,若是任何鏈接的節點失敗,則執行自動恢復。Leader在服務啓動時被選舉。

Follower分佈式

  • 跟隨leader指令的服務器節點。

層次命名空間

ZooKeeper節點稱爲 znode 。每一個znode由一個名稱標識,並用路徑(/)序列分隔。

輸入圖片說明
屏幕截圖.png

  • config 命名空間用於集中式配置管理,workers 命名空間用於命名。
  • 在 config 命名空間下,每一個znode最多可存儲1MB的數據。這與UNIX文件系統相相似,除了父znode也能夠存儲數據。這種結構的主要目的是存儲同步數據並描述znode的元數據。此結構稱爲 ZooKeeper數據模型。
  • ZooKeeper數據模型中的每一個znode都維護着一個 stat 結構。一個stat僅提供一個znode的元數據。它由版本號,操做控制列表(ACL),時間戳和數據長度組成。
  1. 版本號 - 每一個znode都有版本號,這意味着每當與znode相關聯的數據發生變化時,其對應的版本號也會增長。當多個zookeeper客戶端嘗試在同一znode上執行操做時,版本號的使用就很重要。
  2. 操做控制列表(ACL) - ACL基本上是訪問znode的認證機制。它管理全部znode讀取和寫入操做。
  3. 時間戳 - 時間戳表示建立和修改znode所通過的時間。它一般以毫秒爲單位。ZooKeeper從「事務ID"(zxid)標識znode的每一個更改。Zxid是惟一的,而且爲每一個事務保留時間,以便你能夠輕鬆地肯定從一個請求到另外一個請求所通過的時間。
  4. 數據長度 - 存儲在znode中的數據總量是數據長度。你最多能夠存儲1MB的數據。

Znode的類型

Znode被分爲持久(persistent)節點,順序(sequential)節點和臨時(ephemeral)節點。

  • 持久節點 - 即便在建立該特定znode的客戶端斷開鏈接後,持久節點仍然存在。默認狀況下,除非另有說明,不然全部znode都是持久的。
  • 臨時節點 - 客戶端活躍時,臨時節點就是有效的。當客戶端與ZooKeeper集合斷開鏈接時,臨時節點會自動刪除。所以,只有臨時節點不容許有子節點。若是臨時節點被刪除,則下一個合適的節點將填充其位置。臨時節點在leader選舉中起着重要做用。
  • 順序節點 - 順序節點能夠是持久的或臨時的。當一個新的znode被建立爲一個順序節點時,ZooKeeper經過將10位的序列號附加到原始名稱來設置znode的路徑。例如,若是將具備路徑 /myapp 的znode建立爲順序節點,則ZooKeeper會將路徑更改成 /myapp0000000001 ,並將下一個序列號設置爲0000000002。若是兩個順序節點是同時建立的,那麼ZooKeeper不會對每一個znode使用相同的數字。順序節點在鎖定和同步中起重要做用。

Sessions(會話)

  • 會話對於ZooKeeper的操做很是重要。會話中的請求按FIFO順序執行。一旦客戶端鏈接到服務器,將創建會話並向客戶端分配會話ID 。
  • 客戶端以特定的時間間隔發送心跳以保持會話有效。若是ZooKeeper集合在超過服務器開啓時指定的期間(會話超時)都沒有從客戶端接收到心跳,則它會斷定客戶端死機。
  • 會話超時一般以毫秒爲單位。當會話因爲任何緣由結束時,在該會話期間建立的臨時節點也會被刪除。

Watches(監視)

  • 監視是一種簡單的機制,使客戶端收到關於ZooKeeper集合中的更改的通知。客戶端能夠在讀取特定znode時設置Watches。Watches會向註冊的客戶端發送任何znode(客戶端註冊表)更改的通知。
  • Znode更改是與znode相關的數據的修改或znode的子項中的更改。只觸發一次watches。若是客戶端想要再次通知,則必須經過另外一個讀取操做來完成。當鏈接會話過時時,客戶端將與服務器斷開鏈接,相關的watches也將被刪除。

Zookeeper 工做流

一旦ZooKeeper集合啓動,它將等待客戶端鏈接。客戶端將鏈接到ZooKeeper集合中的一個節點。它能夠是leader或follower節點。一旦客戶端被鏈接,節點將向特定客戶端分配會話ID並向該客戶端發送確認。若是客戶端沒有收到確認,它將嘗試鏈接ZooKeeper集合中的另外一個節點。 一旦鏈接到節點,客戶端將以有規律的間隔向節點發送心跳,以確保鏈接不會丟失。

  • 若是客戶端想要讀取特定的znode,它將會向具備znode路徑的節點發送讀取請求,而且節點經過從其本身的數據庫獲取來返回所請求的znode。爲此,在ZooKeeper集合中讀取速度很快。
  • 若是客戶端想要將數據存儲在ZooKeeper集合中,則會將znode路徑和數據發送到服務器。鏈接的服務器將該請求轉發給leader,而後leader將向全部的follower從新發出寫入請求。若是隻有大部分節點成功響應,而寫入請求成功,則成功返回代碼將被髮送到客戶端。 不然,寫入請求失敗。絕大多數節點被稱爲 Quorum 。

ZooKeeper集合中的節點

  • 若是咱們有單個節點,則當該節點故障時,ZooKeeper集合將故障。它有助於「單點故障",不建議在生產環境中使用。
  • 若是咱們有兩個節點而一個節點故障,咱們沒有佔多數,由於兩個中的一個不是多數。
  • 若是咱們有三個節點而一個節點故障,那麼咱們有大多數,所以,這是最低要求。ZooKeeper集合在實際生產環境中必須至少有三個節點。
  • 若是咱們有四個節點而兩個節點故障,它將再次故障。相似於有三個節點,額外節點不用於任何目的,所以,最好添加奇數的節點,例如3,5,7。
  • 寫入過程比ZooKeeper集合中的讀取過程要貴,由於全部節點都須要在數據庫中寫入相同的數據

輸入圖片說明
屏幕截圖.png

寫入(write)

  • 寫入過程由leader節點處理。leader將寫入請求轉發到全部znode,並等待znode的回覆。若是一半的znode回覆,則寫入過程完成。

讀取(read)

  • 讀取由特定鏈接的znode在內部執行,所以不須要與集羣進行交互。

複製數據庫(replicated database)

  • 它用於在zookeeper中存儲數據。每一個znode都有本身的數據庫,每一個znode在一致性的幫助下每次都有相同的數據。

Leader負責處理寫入請求的Znode。

Follower:從客戶端接收寫入請求,並將它們轉發到leader znode。

請求處理器(request processor):只存在於leader節點。它管理來自follower節點的寫入請求。

原子廣播(atomic broadcasts):負責廣播從leader節點到follower節點的變化。

Zookeeper leader選舉

分析如何在ZooKeeper集合中選舉leader節點。考慮一個集羣中有N個節點。leader選舉的過程以下:

  • 全部節點建立具備相同路徑 /app/leader_election/guid_ 的順序、臨時節點。
  • ZooKeeper集合將附加10位序列號到路徑,建立的znode將是 /app/leader_election/guid_0000000001,/app/leader_election/guid_0000000002等。
  • 對於給定的實例,在znode中建立最小數字的節點成爲leader,而全部其餘節點是follower。
  • 每一個follower節點監視下一個具備最小數字的znode。例如,建立znode/app/leader_election/guid_0000000008的節點將監視znode/app/leader_election/guid_0000000007,建立znode/app/leader_election/guid_0000000007的節點將監視znode/app/leader_election/guid_0000000006。
  • 若是leader關閉,則其相應的znode/app/leader_electionN會被刪除。
  • 下一個在線follower節點將經過監視器得到關於leader移除的通知。
  • 下一個在線follower節點將檢查是否存在其餘具備最小數字的znode。若是沒有,那麼它將承擔leader的角色。不然,它找到的建立具備最小數字的znode的節點將做爲leader。
  • 相似地,全部其餘follower節點選舉建立具備最小數字的znode的節點做爲leader。

Zookeeper集羣安裝 安裝:

wget http://www.apache.org/dist//zookeeper/zookeeper-3.3.3/zookeeper-3.3.3.tar.gz
tar zxvf zookeeper-3.3.3.tar.gz
cd zookeeper-3.3.3
cp conf/zoo_sample.cfg conf/zoo.cfg
複製代碼

zookeeper-3.4.10/conf新創建zoo.cfg,zoo2.cfg,zoo3.cfg三個文件,配置以下,

#心跳間隔 毫秒每次
tickTime = 2000
##日誌位置 僞集羣設置不一樣目錄
dataDir = /home/zookeeper-3.4.10/data/data1
#監聽客戶端鏈接的端口 僞集羣設置不一樣端口
clientPort = 2181
#多少個心跳時間內,容許其餘server鏈接並初始化數據,若是ZooKeeper管理的數據較大,則應相應增大這個值
initLimit = 10
#多少個tickTime內,容許follower同步,若是follower落後太多,則會被丟棄
syncLimit = 5

#僞集羣配置 不須要集羣去掉(vim /etc/host 映射ip的hostname的關係)
server.1=CentOS124:2886:3886
server.2=CentOS124:2888:3888
server.3=CentOS124:2889:3889
複製代碼

並在zookeeper-3.4.10/data的 data1,data2,data3 目錄下放置myid文件,文件內容爲1,2,3:

輸入圖片說明
屏幕截圖.png
輸入圖片說明
屏幕截圖.png

進入bi目錄 啓動

./zkServer.sh start zoo.cfg
./zkServer.sh start zoo2.cfg
./zkServer.sh start zoo3.cfg
複製代碼

查看服務狀態

./zkServer.sh status zoo.cfg
./zkServer.sh status zoo2.cfg
./zkServer.sh status zoo3.cfg
複製代碼

使用Zookeeper的客戶端來鏈接並測試了

[root@CentOS124 bin]# ./zkCli.sh

#查看根節點
[zk: localhost:2181(CONNECTED) 0] ls /
[firstNode, SecodeZnode, firstNode0000000002, hbase, zookeeper]
[zk: localhost:2181(CONNECTED) 0] create /mykey1 myvalue1  #建立一個新節點mykey1 
Created /mykey1
[zk: localhost:2181(CONNECTED) 1] get /mykey1   #獲取mykey1節點 

#要建立順序節點
create -s /FirstZnode second-data

#要建立臨時節點
create -e /SecondZnode 「Ephemeral-data" 複製代碼
相關文章
相關標籤/搜索