天天看點

Windows安裝和使用zookeeper

之前整理過一篇文章《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 端口号在監聽服務。

Windows安裝和使用zookeeper

叢集模式

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 所示:

    • Windows安裝和使用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 的學習與運用

原文位址:https://www.cnblogs.com/shanyou/p/3221990.html

繼續閱讀