zookeeper安裝和使用 windows
的 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 端口號在監聽服務。
集群模式
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 這種數據結構有如下這些特點:
- 每個子目錄項如 NameService 都被稱作為 znode,這個 znode 是被它所在的路徑唯一標識,如 Server1 這個 znode 的標識為 /NameService/Server1
- znode 可以有子節點目錄,並且每個 znode 可以存儲數據,註意 EPHEMERAL 類型的目錄節點不能有子節點目錄
- znode 是有版本的,每個 znode 中存儲的數據可以有多個版本,也就是一個訪問路徑中可以存儲多份數據
- znode 可以是臨時節點,一旦創建這個 znode 的客戶端與服務器失去聯系,這個 znode 也將自動刪除,Zookeeper 的客戶端和服務器通信采用長連接方式,每個客戶端和服務器通過心跳來保持連接,這個連接狀態稱為 session,如果 znode 是臨時節點,這個 session 失效,znode 也就刪除了
- znode 的目錄名可以自動編號,如 App1 已經存在,再創建的話,將會自動命名為 App2
- 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安裝和使用 windows