Windows安裝和使用zookeeper

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

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

單機模式git

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

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

# 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 實例,下面將介紹集羣模式的安裝和配置。session

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。

 

示例代碼下載:ZookeeperDemo.zip

相關文章:

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 的學習與運用

相關文章
相關標籤/搜索