Zookeeper服務框架之介紹篇

Zookeeper服務框架之介紹篇

 

Zookeeper是一種分佈式服務框架,是apache hadoop的子項目,完全開源存在,它的誕生主要用來處理分佈式環境中數據管理問題,比如:分佈式應用程序配置、集羣管理、狀態同步服務及命名服務等。這裏,我們以3.4.8版本爲例展開介紹,其最新的版本下載可以從地址:

http://hadoop.apache.org/zookeeper/ 中獲取,並以java項目爲例進行分析和使用Zookeeper,和以往文章一樣,都是以安裝配置開始!

 

l   安裝配置

l   組件特點

l   入門使用

 

 

一、安裝配置

Zookeeper的安裝十分簡單,我們只需要從如下地址下載並解壓:

http://mirrors.cnnic.cn/apache/zookeeper/ 

 

然後,Zookeeper的安裝配置,可以從單機和集羣環境介紹:

1、配置

在開始服務前,有幾個基本配置要準備下,Zookeeper的配置文件在conf文件夾下,默認名爲zoo_sample.cfg,也是Zookeeper默認加載的配置文件,這裏我們把它改個名字:

$sudo mv  zoo_sample.cfg zoo.cfg

 

另外,當前版本的Zookeeper的conf下,還有log4j.properties和configuration.xsl文件,在後續文章中會陸續介紹它們的作用,那麼接下來就先介紹zoo.cfg配置和使用情況。

 

2、單機環境

在單機環境下,滿足服務基本需求的zoo.cfg基本內容如下:

tickTime=2000

dataDir=/zookeeper/zookeeper/build

clientPort=2181

 

參數說明:

tickTime:Zookeeper服務器間或客戶端與服務器之間維持心跳的間隔時間,即每隔tickTime時間,就發送一次心跳檢測。

dataDir:Zookeeper服務保存數據的位置,默認也是其存放寫入數據的日誌文件的位置。

clientPort:Zookeeper會監聽這個端口,來知道客戶端鏈接到它,也就是客戶端鏈接Zookeeper服務器的端口。

 

當配置好之後,我們可以啓動Zookeeper服務了,具體如下:

$sudo  ./zkServer.sh  start

 

啓動的結果:

 

3、集羣環境

Zookeeper不僅可以單機提供服務,同時也支持多機組成集羣來提供服務。實際上 Zookeeper還支持另外一種僞集羣的方式,也就是可以在一臺物理機上運行多個Zookeeper 實例,下面將介紹集羣模式的安裝和配置。

Zookeeper的集羣模式的安裝和配置也不是很複雜,所要做的就是增加幾個配置項。集羣模式除了上面的三個配置項還要增加下面幾個配置項:

 initLimit=5

 syncLimit=2

 server.1=192.168.211.1:2888:3888

 server.2=192.168.211.2:2888:3888

•         initLimit:這個配置項是用來配置 Zookeeper接受客戶端(這裏所說的客戶端不是用戶連接 Zookeeper 服務器的客戶端,而是 Zookeeper 服務器集羣中連接到Leader 的 Follower 服務器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過5 個心跳的時間(也就是 tickTime)長度後 Zookeeper 服務器還沒有收到客戶端的返回信息,那麼表明這個客戶端連接失敗。總的時間長度就是 5*2000=10 秒

•         syncLimit:這個配置項標識 Leader與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個tickTime 的時間長度,總的時間長度就是 2*2000=4 秒

•         server.A=B:C:D:其中 A 是一個數字,表示這個是第幾號服務器;B 是這個服務器的 ip 地址;C 表示的是這個服務器與集羣中的 Leader 服務器交換信息的端口;D 表示的是萬一集羣中的 Leader 服務器掛了,需要一個端口來重新進行選舉,選出一個新的 Leader,而這個端口就是用來執行選舉時服務器相互通信的端口。如果是僞集羣的配置方式,由於 B 都是一樣,所以不同的 Zookeeper 實例通信端口號不能一樣,所以要給它們分配不同的端口號。

除了修改 zoo.cfg 配置文件,集羣模式下還要配置一個文件 myid,這個文件在 dataDir 目錄下,這個文件裏面就有一個數據就是 A 的值,Zookeeper 啓動時會讀取這個文件,拿到裏面的數據與 zoo.cfg 裏面的配置信息比較從而判斷到底是那個 server。

 

 

NOTE:

停止:zkServer.shstop

重啓:zkServer.shrestart

啓動:  zkServer.sh start

 

二、組件特點

1、數據結構

Zookeeper本身提供和維護了一個有層次關係的數據結構,類似標準的文件系統,不同的是Zookeeper文件系統的每個節點znode,都可以存儲數據,而znode目前有四種類型:臨時節點、臨時順序編號節點、持久化節點及持久化順序編號節點,那麼接下來結合網絡上的數據結構圖說明:

 

特點說明:

A、每個znode節點,都可以擁有子節點,並且都可以存儲數據(除了臨時節點EPHEMERAL);

B、每個znode節點,都被它所在的路徑唯一標註,比如:NameService下的Server1,被唯一的標識爲:/NameService/Server1;

C、每個znode節點,都有版本的,也就是該節點的路徑下,存放多份版本的數據;

D、每個znode節點,都可以自動編號,比如:已經存在App1節點,那麼再創建App1節點時,會自動創建App2節點;

E、每個znode臨時節點,當客戶端與服務端斷開鏈接後,znode也自動被刪除;

F、每個znode節點都可以被監控,包含該節點存放的數據及其子目錄結構或數據被修改時,會立即通知發起該設置的客戶端;

G、客戶端與服務端的鏈接爲長鏈接,彼此間採用心跳方式保持通信,這個鏈接狀態爲session狀態,所以如果某個znode節點爲臨時節點,那麼這個session就不起作用了;

 

 

2、工作特點

 

原理說明:

A、Zookeeper服務核心是原子廣播,它保證了各個參與的Server間同步,實現它協議爲Zab協議,它分爲恢復模式和廣播模式。當服務啓動或者在領導者崩潰後,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和 leader的狀態同步以後,恢復模式就結束了。狀態同步保證了leader和Server具有相同的系統狀態。

B、Zookeeper服務持續監聽所有註冊的znode節點,一旦節點的結構、數據發生變化時,leader節點會監控到變化並更新系統狀態值,所有follower和observer節點,會向leader節點的數據狀態同步,這也是Zookeeper在分佈式環境的核心作用;

C、所有的observer的znode節點,都可接收客戶端的鏈接,也會從leader節點同步更新最新的數據版本,但其不參與leader的投票動作,會將客戶端的寫入數據請求轉發給leader節點處理;

D、所有的follower的znode節點,都有資格參與leader的投票選擇,也會自動從leader節點更新同步數據版本,也處理客戶端的請求及返回結果;

 

 

3、設計目的

A、原子性,各個znode節點數據只有更新成功或失敗,沒有中間狀態;

B、可靠性,如果一條消息被一臺服務器接收,那麼其它各個服務器都會接收,保證了數據的一致性;

C、實時性,Zookeeper可保證客戶端將在一個時間間隔範圍內獲得服務器的更新信息,或者服務器失效的信息。但由於網絡延時等原因,Zookeeper不能保證兩個客戶端能同時得到最新的數據,如果需要最新數據,應該在讀取數據之前調用sync()接口,來手動獲取最新的數據版本;

D、等待無關性,無效的或是阻塞的客戶端鏈接,不影響其它任務客戶端鏈接,各個鏈接客戶端彼此獨立鏈接;

E、一致性,客戶端不論連接到哪個服務器上,展示給它都是同一個視圖,這是Zookeeper最重要的性能。 

 

 

三、如何使用

基本使用如下,比較簡單:

publicstatic void main(String[] args) {

            try{

                   // 創建一個與服務器的連接

                   ZooKeeper zk = new ZooKeeper("localhost:"+ 2181,

                          200000, new Watcher() {

                              // 監控所有被觸發的事件

                              public voidprocess(WatchedEvent event) {

                                  log("已經觸發了" + event.getType() + "事件!");

                              }

                          });

                   // 創建一個目錄節點

                   zk.create("/testRootPath", "testRootData".getBytes(),Ids.OPEN_ACL_UNSAFE,

                     CreateMode.PERSISTENT);

                   // 創建一個子目錄節點

                   zk.create("/testRootPath/testChildPathOne","testChildDataOne".getBytes(),

                     Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);

                   log(new String(zk.getData("/testRootPath",false,null)));

                   // 取出子目錄節點列表

                   log(zk.getChildren("/testRootPath",true));

                   // 修改子目錄節點數據

                   zk.setData("/testRootPath/testChildPathOne","modifyChildDataOne".getBytes(),-1);

                   log("目錄節點狀態:["+zk.exists("/testRootPath",true)+"]");

                   // 創建另外一個子目錄節點

                   zk.create("/testRootPath/testChildPathTwo","testChildDataTwo".getBytes(),

                     Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);

                   log(new String(zk.getData("/testRootPath/testChildPathTwo",true,null)));

                   // 刪除子目錄節點

                   zk.delete("/testRootPath/testChildPathTwo",-1);

                   zk.delete("/testRootPath/testChildPathOne",-1);

                   // 刪除父目錄節點

                   zk.delete("/testRootPath",-1);

                   

                   // 關閉連接

                   zk.close();

            }catch (IOException e) {

                  e.printStackTrace();

            }catch (KeeperException | InterruptedException e) {

                  e.printStackTrace();

            }

      }

 

privatestatic void log(Object msg) {

            System.out.println(msg);

      }

 

 

 

運行結果如下:

 

 

 

 

 

 

 

 

 

 

 

 

分佈式服務框架之Zookeeper就介紹到這裏,由於作者水平有限,如有問題請在評論發言或是QQ羣(245389109(新))討論,謝謝。

 

 

 

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