Windows安裝和使用zookeeper

源自:http://www.cnblogs.com/shanyou/p/3221990.html


之前整理過一篇文章《zookeeper 分佈式鎖服務》,本文介紹的 Zookeeper 是以 3.4.5 這個穩定版本爲基礎,最新的版本可以通過官網 http://hadoop.apache.org/zookeeper/來獲取,Zookeeper 的安裝非常簡單,下面將從單機模式和集羣模式兩個方面介紹 Zookeeper 的Windows安裝和配置.

首先需要安裝JdK,從Oracle的Java網站下載,安裝很簡單,就不再詳述。

單機模式

單機安裝非常簡單,只要獲取到 Zookeeper 的壓縮包並解壓到某個目錄如:C:\zookeeper-3.4.5\下,Zookeeper 的啓動腳本在 bin 目錄下,Windows 下的啓動腳本是 zkServer.cmd。

在你執行啓動腳本之前,還有幾個基本的配置項需要配置一下,Zookeeper 的配置文件在 conf 目錄下,這個目錄下有 zoo_sample.cfg 和 log4j.properties,你需要做的就是將 zoo_sample.cfg 改名爲 zoo.cfg,因爲 Zookeeper 在啓動時會找這個文件作爲默認配置文件。下面詳細介紹一下,這個配置文件中各個配置項的意義。

# The number of milliseconds of each tick
tickTime=2000
# 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=C:\\zookeeper-3.4.5\\data
dataLogDir=C:\\zookeeper-3.4.5\\log
# the port at which the clients will connect
clientPort=2181
#
# 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
  • tickTime:這個時間是作爲 Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發送一個心跳。
  • dataDir:顧名思義就是 Zookeeper 保存數據的目錄,默認情況下,Zookeeper 將寫數據的日誌文件也保存在這個目錄裏。
  • dataLogDir:顧名思義就是 Zookeeper 保存日誌文件的目錄
  • clientPort:這個端口就是客戶端連接 Zookeeper 服務器的端口,Zookeeper 會監聽這個端口,接受客戶端的訪問請求。

當這些配置項配置好後,你現在就可以啓動 Zookeeper 了,啓動後要檢查 Zookeeper 是否已經在服務,可以通過 netstat – ano 命令查看是否有你配置的 clientPort 端口號在監聽服務。

image

集羣模式

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 服務器)初始化連接時最長能忍受多少個心跳時間間隔數。當已經超過 10 個心跳的時間(也就是 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。

數據模型

Zookeeper 會維護一個具有層次關係的數據結構,它非常類似於一個標準的文件系統,如圖 1 所示:

    • zookeeper

Zookeeper 這種數據結構有如下這些特點:

  1. 每個子目錄項如 NameService 都被稱作爲 znode,這個 znode 是被它所在的路徑唯一標識,如 Server1 這個 znode 的標識爲 /NameService/Server1
  2. znode 可以有子節點目錄,並且每個 znode 可以存儲數據,注意 EPHEMERAL 類型的目錄節點不能有子節點目錄
  3. znode 是有版本的,每個 znode 中存儲的數據可以有多個版本,也就是一個訪問路徑中可以存儲多份數據
  4. znode 可以是臨時節點,一旦創建這個 znode 的客戶端與服務器失去聯繫,這個 znode 也將自動刪除,Zookeeper 的客戶端和服務器通信採用長連接方式,每個客戶端和服務器通過心跳來保持連接,這個連接狀態稱爲 session,如果 znode 是臨時節點,這個 session 失效,znode 也就刪除了
  5. znode 的目錄名可以自動編號,如 App1 已經存在,再創建的話,將會自動命名爲 App2
  6. znode 可以被監控,包括這個目錄節點中存儲的數據的修改,子節點目錄的變化等,一旦變化可以通知設置監控的客戶端,這個是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基於這個特性實現的,後面在典型的應用場景中會有實例介紹

如何使用

Zookeeper 作爲一個分佈式的服務框架,主要用來解決分佈式集羣中應用系統的一致性問題,它能提供基於類似於文件系統的目錄節點樹方式的數據存儲,但是 Zookeeper 並不是用來專門存儲數據的,它的作用主要是用來維護和監控你存儲的數據的狀態變化。通過監控這些數據狀態的變化,從而可以達到基於數據的集羣管理.

通過C#代碼使用zookeeper

Zookeeper的使用主要是通過創建其Nuget ZooKeeperNet包下的Zookeeper實例,並且調用其接口方法進行的,主要的操作就是對znode的增刪改操作,監聽znode的變化以及處理。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZooKeeperNet;

namespace ZookeeperDemo
{
    class Watcher : IWatcher
    {
        public void Process(WatchedEvent @event)
        {
            if (@event.Type == EventType.NodeDataChanged)
            {
                Console.WriteLine(@event.Path);
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ZooKeeperNet;

namespace ZookeeperDemo
{
    class Program
    {
        static void Main(string[] args)
        {

            //創建一個Zookeeper實例,第一個參數爲目標服務器地址和端口,第二個參數爲Session超時時間,第三個爲節點變化時的回調方法 
            using (ZooKeeper zk = new ZooKeeper("127.0.0.1:2181", new TimeSpan(0, 0, 0, 50000), new Watcher()))
            {
                var stat = zk.Exists("/root",true);
                 
                ////創建一個節點root,數據是mydata,不進行ACL權限控制,節點爲永久性的(即客戶端shutdown了也不會消失) 
                //zk.Create("/root", "mydata".GetBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.Persistent);

                //在root下面創建一個childone znode,數據爲childone,不進行ACL權限控制,節點爲永久性的 
                zk.Create("/root/childone", "childone".GetBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.Persistent);
                //取得/root節點下的子節點名稱,返回List<String> 
                zk.GetChildren("/root", true);
                //取得/root/childone節點下的數據,返回byte[] 
                zk.GetData("/root/childone", true, null);

                //修改節點/root/childone下的數據,第三個參數爲版本,如果是-1,那會無視被修改的數據版本,直接改掉
                zk.SetData("/root/childone", "childonemodify".GetBytes(), -1);
                //刪除/root/childone這個節點,第二個參數爲版本,-1的話直接刪除,無視版本 
                zk.Delete("/root/childone", -1);
            }

        }
    }
}

 

淺析

創建連接:

1.獲取服務主機列表

2.設置超時時間

3.註冊客戶端事件

4.以線程安全的方式創建請求連接(啓動客戶端請求隊列,循環隊列基於socket通信、根據請求類型執行不同的請求動作)

請求流程:

構造請求頭、構造request,reponse、構造響應頭、構造Packet對象,packet對象準備好後,把整個對象放入一個outgoingQueue 
packet被放入outgoingQueue中,等待SendThread把packet對應的內容發送給server。server處理分3步在doio方法中ReadLength ReadConnectResult ReadResponse,直到ReadResponse方法中確定packet請求結束。

響應流程:

針對心跳的ping請求的resp,針對auth請求的resp,一般接口請求的resp,如果接口請求要求了watcher,當watcher關注的內容有變化時的notification

鎖相關部分API方法:

創建節點:create

demo:zk.Create(Dir, severname.GetBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.Persistent);

其中CreateMode分爲4類Persistent、PersistentSequential、Ephemeral、EphemeralSequential

PERSISTENT 創建持久化節點,對應機器關閉連接後節點/數據不會消失

PERSISTENT_SEQUENTIAL 如果PATH是以’/’結尾則以這個PATH作爲父節點,創建一個子節點,其子節點名字是一個按先後順序排列的數值;否則創建一個名字是‘/’後面字符加上先後順序排列的數值字符串的節點,同樣創建持久節點

EPHEMERAL 創建瞬時節點,Zookeeper在感知連接機器宕機後會清除它創建的瞬時節點

EPHEMERAL_SEQUENTIAL 穿件瞬時順序節點,和PERSISTENT_SEQUENTIAL一樣,區別在於它是瞬時的

刪除節點 delete

demo :zk.Delete(Dir, -1);

前一個參數代表節點名稱(一般用作路徑),後一個是版本號 -1表示全匹配

查看節點 exists

demo : zk.Exists(Dir, new MyWatch2());

獲取數據 getData

demo :zk.GetData(Dir, new MyWatch2(), stat);

獲取一個節點的數據,可注入watcher 

設置數據 setData

demo : zk.SetData(Dir, new byte[1], 1);

獲取下級節點集合 GetChildren

demo :zk.GetChildren(Dir, true);

存儲

znodes類似文件和目錄。但它不是一個典型的文件系統,zookeeper數據保存在內存中,這意味着zookeeper可以實現高吞吐量和低延遲。

watcher

Zookeeper有兩種watches,一種是data watches,另一種是child watches。其中,getData()和exists()以及create()等會添加data watches,getChildren()會添加child watches。而delete()涉及到刪除數據和子節點,會同時觸發data watches和child watches。

 

ZooKeeper配置 (二)

zookeeper 安裝配置(三)

Zookeeper .Net Client

https://github.com/devhong/Zookeeper.Net

基於ZooKeeper構建大規模配置系統II http://xahxy.blog.hexun.com/83250722_d.html

分佈式服務框架 Zookeeper -- 管理分佈式環境中的數據 http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/

基於ZooKeeper的分佈式Session實現 http://blog.csdn.net/jacktan/article/details/6112806

ZooKeeper介紹、分析、理解  http://mazd1002.blog.163.com/blog/static/6657496520111120101753463/

ZooKeeper實現分佈式隊列Queue http://blog.fens.me/zookeeper-queue/ 

李欣:ZooKeeper在攜程的使用及前景 http://v.csdn.hudong.com/open/view/detail/83-SDCC2012-ctrip-ZooKeeper

Storm-源碼分析- Storm中Zookeeper的使用

Zookeeper 的學習與運用


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