1. 程式人生 > >大資料框架開發基礎之Zookeeper入門

大資料框架開發基礎之Zookeeper入門

Zookeeper是Hadoop分散式排程服務,用來構建分散式應用系統。構建一個分散式應用是一個很複雜的事情,主要的原因是我們需要合理有效的處理分散式叢集中的部分失敗的問題。例如,叢集中的節點在相互通訊時,A節點向B節點發送訊息。A節點如果想知道訊息是否傳送成功,只能由B節點告訴A節點。那麼如果B節點關機或者由於其他的原因脫離叢集網路,問題就出現了。A節點不斷的向B傳送訊息,並且無法獲得B的響應。B也沒有辦法通知A節點已經離線或者關機。叢集中其他的節點完全不知道B發生了什麼情況,還在不斷的向B傳送訊息。這時,你的整個叢集就發生了部分失敗的故障。

Zookeeper不能讓部分失敗的問題徹底消失,但是它提供了一些工具能夠讓你的分散式應用安全合理的處理部分失敗的問題。

Zookeeper基本

是什麼

是一個基於觀察者模式設計的分散式服務管理框架,他負責儲存和管理大家都關心的資料,然後接受管擦者的註冊,一旦這些資料的狀態發生了變化,Zookeeper就將負責通知已經在Zookeeper上註冊的觀察者做出相應的反應。

特點是什麼

  1. 叢集中半數以上的機器存活,Zookeeper叢集就可以正常服務。

  2. 叢集資料保持一致,每一個Server儲存一分相同的資料副本,Client無論連線那個Server,資料都是一致的。

Zookeeper的工作機制

Zookeeper 特點

  • Zookeeper: 一個領導者(Leader) , 多個追隨者(Follower) 組成的叢集;
  • 叢集中只要有半數以上節點存活,Zookeeper 叢集就能正常服務;
  • 全域性資料一致,每個Server儲存一份相同的資料副本,Client 無論連線到哪個 Server , 資料都是一致的。
  • 更新請求順序進行,來自同一個Client 的更新請求按其傳送順序依次執行;
  • 資料更新原子性,一次資料更新要麼成功,要麼失敗。
  • 實時性,在一定時間範圍內,Client能讀到最新的資料。

Zookeeper 的重要概念

  • Zookeeper 本身就是一個分散式程式(半數以上的節點存活,Zookeeper 就能正常服務)
  • 為了保證高可用,最好是以叢集形態來部署 Zookeeper , 這樣只要叢集中大部分機器是可用的(能夠容忍一定的機器故障),那麼Zookeeper 本身任然是可用的。
  • Zookeeper 將資料儲存在記憶體中,這也就保證了高吞吐量和低延遲(但是記憶體限制了能夠儲存的容量不太大,此限制也是保持 znode 中儲存的資料量較小的進一步原因)。
  • Zookeeper 是高效能的。在 “讀” 多於 “寫” 的應用程式中尤其的 高效能。因為“寫” 會導致所有的伺服器間同步狀態(“讀” 多於 “寫” 是協調服務的典型場景)。
  • Zookeeper 有臨時節點的概念。當建立臨時節點的客戶端會話一直保持活動,瞬時節點就一直存在。而當會話終結時,瞬時節點被刪除。持久節點是指一旦這個 ZNode 被建立,除非主動進行 ZNode 的移除操作,否則這個 ZNode 將一直儲存在 Zookeeper 上。
  • Zookeeper 底層其實只提供了兩個功能:① 管理(儲存、讀取)使用者程式提交的資料; ② 為使用者程式提交資料節點監聽服務

Session (會話)

Session 是指 Zookeeper 伺服器與客戶端會話。在 Zookeeper 中,一個客戶端連線是指客戶端和伺服器之間的 TCP 長連線。客戶端啟動的時候,首先會和伺服器建立一個 TCP 連線,客戶端能夠通過 心跳 檢測和服務保持有效的會話,也能夠向 Zookeeper 伺服器傳送請求並接受響應,同時還能通過該連結接收來自伺服器的 Watch 事件通知。

Session 的 sessionTimeout 值用來設定一個客戶端會話的超時時間。當用於伺服器壓力太大、網路故障或是在客戶端主動斷開連線等各種原因導致客戶端連線斷開的時,只要在 sessionTimeout 規定的時間內能夠重新連線上叢集中任意一臺伺服器,那麼之前建立的會話依然有效。

在為客戶端建立會話之前,服務端首先會為每個客戶端都分配一個 sessionID , 由於 sessionID 是 Zookeeper 會話的一個重要標識,許多與會話相關的執行機制都是基於這個 sessionID 的(也就是,這個 sessionID 全域性唯一) 。

Znode

在分散式中,所謂的節點是指叢集中的每一臺機器,稱為機器節點。但是在 Zookeeper 中, 我們的節點有兩種,一種是 機器節點 , 另一種就是 資料模型中的資料單元,也就是我們稱為的資料節點——Znode 。

Zookeeper 將所有的資料儲存在記憶體中,資料模型是一個 Znode Tree 。主節點是 / ,如下所示:

在節點中,我們又有持久節點和臨時節點一說。所謂持久節點,除非你進行了ZNode的移除操作,否則 Zookeeper 將一直保留在 Zookeeper 上。臨時節點不同的是,它的生命週期和當前會話一致。一旦會話結束,這個臨時節點也就結束了。另外,Zookeeper 允許使用者為每個節點新增一個特殊屬性: SEQUENTIAL , 一旦節點被標記上這個屬性,那麼在節點被建立的時候,Zookeeper 會自動在其節點後面追加上一個整型數字,這個數字是一個由父節點維護的自增數字。

版本

每個 Znode 上都會儲存資料,對應每個 ZNode , Zookeeper 會維護一個 Stat 的資料結構。 Stat 記錄了這個 ZNode 的三個資料版本,分別是 version(當前的 ZNode 版本),cversion(當前 ZNode 子節點的版本), 和 cversion(當前 ZNode 的 ACL 版本)。

Watcher

Watcher(事件監聽器), 是Zookeeper 中的一個很重要的特性。Zookeeper 允許使用者在指定節點上註冊一些 Watcher ,並且在一些特定事件觸發的時候, Zookeeper 服務端 會將事件通知到感興趣的客戶端上去,該機制是 Zookeeper 實現分散式協調服務的重要特性。

ACL

Zookeeper 通過採用 ACL (aCCESSControlLists) 策略來進行許可權控制。有如下五種許可權:

  • create:建立子節點的許可權
  • READ:獲取節點資料和子節點列表的許可權
  • WRITE:更新節點的許可權
  • DELETE:刪除節點的許可權
  • ADMIN:設定節點ACL許可權

Zookeeper 內部原理

選舉機制

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

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

3)以一個簡單的例子來說明整個選舉的過程。

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

(1)伺服器1啟動,此時只有它一臺伺服器啟動了,它發出去的報文沒有任何響應,所以它的選舉狀態一直是LOOKING狀態。

(2)伺服器2啟動,它與最開始啟動的伺服器1進行通訊,互相交換自己的選舉結果,由於兩者都沒有歷史資料,所以id值較大的伺服器2勝出,但是由於沒有達到超過半數以上的伺服器都同意選舉它(這個例子中的半數以上是3),所以伺服器1、2還是繼續保持LOOKING狀態。

(3)伺服器3啟動,根據前面的理論分析,伺服器3成為伺服器1、2、3中的老大,而與上面不同的是,此時有三臺伺服器選舉了它,所以它成為了這次選舉的Leader。

(4)伺服器4啟動,根據前面的分析,理論上伺服器4應該是伺服器1、2、3、4中最大的,但是由於前面已經有半數以上的伺服器選舉了伺服器3,所以它只能接收當小弟的命了。

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

Stat 資料結構

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子節點數量

監聽器原理

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

Zookeeper的叢集搭建

這是我的zookeeper的叢集環境配置:

# The number of milliseconds of each tick
tickTime=30000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/opt/module/zookeeper-3.4.10/dataDir
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.101=hadoop101:2888:3888
server.102=hadoop102:2888:3888
server.103=hadoop103:2888:3888

在我們的 /opt/module/zookeeper-3.4.10/dataDir中,我們需要新增 myid檔案,且每個節點的myid內容必須保持不一致,如筆者的分別為:101,102,103.內容如下:

101

隨後,我們便分發到各個機器上去。按要求修改相應的2內容。

Zookeeper的基本命令操作

我們看下Zookeeper的客戶端操作:

1.進入客戶端

  bin/zkCli.sh

2.顯示所有的操作命令

  help

3.檢視當前znode中包含的內容

  ls /

4.檢視當前znode中詳細資料資訊

  ls2 /

5.分別建立2個普通節點

  create /sanguo "jinlian"
  create /sanguo/shuguo "liubei"

6.獲得節點的值

  get /sanguo

7.建立短暫節點

  create -e /sanguo/wuguo "zhouyu"
  # 僅在當前客戶端下可以看到的目錄,退出當前客戶端或者使用第二客戶端當前所建立的目錄軍備自動刪除

8.建立帶序號的節點

  # 先建立一個普通的根節點
  create /sanguo/weiguo "caocao"
  # 開始建立一個帶序號的節點
  create -s /sanguo/weiguo/xiaoqiao "jinlian"
  create -s /sanguo/weiguo/daqiao "jinlian"
  create -s /sanguo/weiguo/diaocan "jinlian"

9.修改節點資料值

  set /sanguo/weiguo "simayi"

10.節點的值變化監聽

  get /sanguo watch

11.節點的子節點變化監聽(路徑變化)

  # 在hadoop104主機上註冊監聽/sanguo節點的子節點變化
  ls /sanguo watch
  # 在hadoop103主機/sanguo節點上建立子節點
  create /sanguo/jin "simayi" Created /sanguo/jin
  # 觀察hadoop104主機收到子節點變化的監聽

12.刪除節點

  delete /sanguo/jin

13.遞迴刪除節點

  rmr /sanguo/shuguo

14.檢視節點狀態

  stat /sanguo

Zookeeper API

這部分內容,後續有時間在寫,目前這個API用的比較少,至少我所在的公司不會有這個要求。讀者也可以在網上搜索,會有一大堆的