標籤:des style class blog code java
本文介紹的 Zookeeper 是以 3.4.5 這個穩定版本為基礎,最新的版本可以通過官網 http://hadoop.apache.org/zookeeper/來擷取,Zookeeper 的安裝非常簡單,下面將從單機模式和叢集模式兩個方面介紹 Zookeeper 的Windows安裝和配置.
CSDN:http://download.csdn.net/detail/javadxz/7484051
首先需要安裝JdK,從Oracle的Java網站下載,安裝很簡單,就不再詳述。
單機模式
單機安裝非常簡單,只要擷取到 Zookeeper 的壓縮包並解壓到某個目錄如:C:\zookeeper-3.4.5\下,Zookeeper 的啟動指令碼在 bin 目錄下,Windows 下的啟動指令碼是 bin目錄下的zkServer.cmd。
在你執行啟動指令碼之前,還有幾個基本的配置項需要配置一下,Zookeeper 的設定檔在 conf 目錄下,這個目錄下有 zoo_sample.cfg 和 log4j.properties,你需要做的就是將 zoo_sample.cfg 改名為 zoo.cfg,因為 Zookeeper 在啟動時會找這個檔案作為預設設定檔。下面詳細介紹一下,這個設定檔中各個配置項的意義。
# The number of milliseconds of each ticktickTime=2000# The number of ticks that the initial # synchronization phase can takeinitLimit=10# The number of ticks that can pass between # sending a request and getting an acknowledgementsyncLimit=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\\datadataLogDir=C:\\zookeeper-3.4.5\\log# the port at which the clients will connectclientPort=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