大數據開發系列之Zookeeper
一:ZooKeeper簡介
1、背景
隨著互聯網技術的高速發展,對計算和存儲能力要求越來越高。單純依靠少量的高性能伺服器完成計算任務,已經無法瞞住需求了。IT架構逐步從集中式向分散式過渡。然而,分散式系統涉及到複雜、不穩定的等問題。
2、簡介
Zookeeper可以將這些複雜的、容易出錯的分散式一致性服務封裝起來,構成一個高效可靠的原語集,並提供一些列簡單易用的介面給用戶使用。
特點
1、源碼開放。
2、分散式協調服務,解決分散式數據一致性問題。
3、高性能
4、通過調用Zookeeper提供的介面來解決一些分散式的問題。
3、應用場景
分散式系統,實現高效可靠常會有如下應用需求:
(1)數據發布和訂閱
分散式系統數據一致性,通常是使用數據發布和訂閱形式實現。
傳統的發布訂閱有:"推"和"拉"兩種模式。」推」:伺服器將數據推送給客戶機。」拉」:客戶機從伺服器定時拉去信息。
Zookeeper可以實現兩者結合的方式,實現分散式系統數據一致性。
(2)負載均衡
每個客戶服務可以在Zookeeper上創建屬於自己的節點,節點維護相關的信息,包括鏈接信息數,當某一個節點鏈接快慢的時候,將其切換到其他節點上,實現負責均衡。
(3)命名服務
ZooKeeper通過ID的形式,提供名稱服務。一種是自增長,一種是UUID。
(4)心跳檢查
上面提過客戶服務在ZooKeeper上註冊節點,Zookeeper只需要判斷這些節點是否可用,從而實現心跳檢查。
二:Zookeeper數據模型
Zookeeper本身提供和維護了一個有層次關係的數據結構,類似標準的文件系統,不同的是Zookeeper文件系統的每個節點znode,都可以存儲數據,而znode目前有四種類型:臨時節點、臨時順序編號節點、持久化節點及持久化順序編號節點,那麼接下來結合網路上的數據結構圖說明:
A、層次化的目錄結構,命名符合常規文件系統規範。
B、每個節點在zookeeper中叫做znode,並且其有一個唯一的路徑標識。比如:NameService下的Server1,被唯一的標識為:/NameService/Server1。
C、節點Znode可以包含數據和子節點。
D、每個znode節點,都有版本的,也就是該節點的路徑下,存放多份版本的數據。
E、每個znode節點,都客戶端應用可以在節點上設置監視器 。
F、Znode有兩種類型,短暫的(ephemeral)和持久的(persistent)。
G、Znode的類型在創建時確定並且之後不能再修改。
H、短暫znode的客戶端會話結束時,zookeeper會將該短暫znode刪除,短暫znode不可以有子節點。
I、持久znode不依賴於客戶端會話,只有當客戶端明確要刪除該持久znode時才會被刪除。
三、 Zookeeper工作原理
1、核心概念
leader:是整個Zookeeper集群工作機制的核心。負責進行投票的發起和決議,更新系統狀態。
Observer:同步leader的狀態。
follower:由 leader分派,任務,接受客戶端請求並想客戶端返回結果,在選主過程中參與投票。
Watcher: 在 ZooKeeper 是一個核心功能,Watcher 可以監控目錄節點的數據變化以及子目錄的變化,一旦這些狀態發生變化,伺服器就會通知所有設置在這個目錄節點上的 Watcher,從而每個客戶端都很快知道它所關注的目錄節點的狀態發生變化,而做出相應的反應。
ACL:每個znode被創建時都會帶有一個ACL,用於決定誰可以對它執行何種操作。
2、工作原理
A、Zookeeper服務核心是原子廣播,它保證了各個參與的Server間同步,實現它協議為Zab協議,它分為恢復模式和廣播模式。當服務啟動或者在領導者崩潰後,Zab就進入了恢復模式,當領導者被選舉出來,且大多數Server完成了和 leader的狀態同步以後,恢復模式就結束了。狀態同步保證了leader和Server具有相同的系統狀態。
廣播模式:數據同步模式。恢復模式:leader選舉模式。
B、Zookeeper服務持續監聽所有註冊的znode節點,一旦節點的結構、數據發生變化時,leader節點會監控到變化並更新系統狀態值,所有follower和observer節點會向leader節點的數據狀態同步,這也是Zookeeper在分散式環境的核心作用。
C、所有的observer的znode節點,都可接收客戶端的鏈接,也會從leader節點同步更新最新的數據版本,但其不參與leader的投票動作,會將客戶端的寫入數據請求轉發給leader節點處理;
D、所有的follower的znode節點,都有資格參與leader的投票選擇,也會自動從leader節點更新同步數據版本,也處理客戶端的請求及返回結果;
3、設計理念
A、原子性,各個znode節點數據只有更新成功或失敗,沒有中間狀態;
B、可靠性,如果一條消息被一台伺服器接收,那麼其它各個伺服器都會接收,保證了數據的一致性;
C、實時性,Zookeeper可保證客戶端將在一個時間間隔範圍內獲得伺服器的更新信息,或者伺服器失效的信息。但由於網路延時等原因,Zookeeper不能保證兩個客戶端能同時得到最新的數據,如果需要最新數據,應該在讀取數據之前調用sync()介面,來手動獲取最新的數據版本;
D、等待無關性,無效的或是阻塞的客戶端鏈接,不影響其它任務客戶端鏈接,各個鏈接客戶端彼此獨立鏈接;
E、一致性,客戶端不論連接到哪個伺服器上,展示給它都是同一個視圖,這是Zookeeper最重要的性能。
四、下載安裝
1、下載地址
https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.6/
2、解壓
tar -zxvf zookeeper-3.4.6.tar.gz
3、配置
$ZOOKEEPER/conf下配置zoo.cfg
mv zoo_sample.cfg zoo.cfg
initLimit=10
syncLimit=5
clientPort=2181
tickTime=2000
dataDir=/var/zookeeper
dataLogDir=/var/zookeeper
initLimit:啟動時間
………………………………………………….單機安裝,上面配置即可
server.1=192.168.1.112:2888:3888
server.2=192.168.1.111:2888:3888
server.3=192.168.1.115:2888:3888
配置詳解:
syncLimit:leader監聽到節點狀態變化後,同步到leader及Listner節點時間
tickTime :這個時間是作為 Zookeeper 伺服器之間或客戶端與伺服器之間維持心跳的時間間隔。
dataDir:顧名思義就是 Zookeeper 保存數據的目錄,默認情況下,Zookeeper 將寫數據的日誌文件也保存在這個目錄里;
clientPort:這個埠就是客戶端連接 Zookeeper 伺服器的埠,Zookeeper 會監聽這個埠,接受客戶端的訪問請求。當這些配置項配置好後,就可以啟動 Zookeeper 了,啟動後使用命令echo ruok | nc localhost 2181檢查 Zookeeper 是否已經在服務
在(dataDir=/itcast/zookeeper-3.4.5/data)創建一個myid文件,裡面內容是server.N中的N(server.2裡面內容為2)echo "5" > myid
4、啟動/關閉
啟動:
分別在3台機器上啟動ZooKeeper的Server:sh bin/zkServer.sh start;
關閉:
分別在3台機器上啟動ZooKeeper的Server:sh bin/zkServer.sh stop;
查看:
jps
五、 客戶端Shell操作
1、連接ZooKeeper服務
zkCli.sh-server host:port cmd args
eg:./zkCli.sh-server 192.168.8.130:2181
2、查看節點
ls /
3、創建節點並存儲數據
create /app1 "this is app1"
持久帶序號 create -s
持久不帶序號 create
短暫帶序號 create -s -e
短暫不帶序號 create –e
4、獲取節點內容
get /app1
5、修改節點內容
set /lijie/test 66666
6、節點狀態
stat /node_5
六、 客戶端Java操作
1、 ZooKeeper項目資源引入
2、基本開發模型
(1)同步通信模式開發
importjava.io.IOException;
publicclassCreateNodeSyncimplementsWatcher{
privatestaticZooKeeperzooKeeper=null;
publicstaticvoidmain(String[]args)throwsException {
zooKeeper=newZooKeeper("192.168.8.130:2181",5000,newCreateNodeSync());
Thread.sleep(Integer.MAX_VALUE);
}
publicvoiddoSomething(){
try{
Stringinfo=zooKeeper.create("/node_4","123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
}catch(Exceptione) {
//TODOAuto-generated catch block
e.printStackTrace();
}
}
@Override
publicvoidprocess(WatchedEventevent) {
if(event.getState()==KeeperState.SyncConnected){
doSomething();
}
}
}
(2)非同步通信模式開發
importjava.io.IOException;
publicclassCreateNodeAsyncimplementsWatcher{
privatestaticZooKeeperzooKeeper=null;
publicstaticvoidmain(String[]args)throwsException {
zooKeeper=newZooKeeper("192.168.8.130:2181",5000,newCreateNodeAsync());
Thread.sleep(Integer.MAX_VALUE);
}
publicvoiddoSomething(){
try{
zooKeeper.create("/node_5","123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT,newIStringCallBack(),"創建");
}catch(Exceptione) {
//TODOAuto-generated catch block
e.printStackTrace();
}
}
@Override
publicvoidprocess(WatchedEventevent) {
if(event.getState()==KeeperState.SyncConnected){
doSomething();
}
}
staticclassIStringCallBackimplementsAsyncCallback.StringCallback{
//rc-返回碼,path-需要創建節點的完整路徑,name-已經創建節點真實路徑
@Override
publicvoidprocessResult(intrc, Stringpath, Objectctx, Stringname) {
//TODOAuto-generated method stub
}
}
}
%1、 Java API介面
String create(String path, byte[] data, List acl, CreateMode createMode)
Stat exists(String path, boolean watch)
void delete(String path, int version)
List getChildren(String path, boolean watch)
List getChildren(String path, boolean watch)
創建一個給定的目錄節點 path, 並給它設置數據;判斷某個 path 是否存在,並設置是否監控這個目錄節點,這裡的 watcher 是在創建 ZooKeeper 實例時指定的 watcher,exists方法還有一個重載方法,可以指定特定的 watcher ;重載方法,這裡給某個目錄節點設置特定的 watcher;刪除 path 對應的目錄節點,version 為 -1 可以匹配任何版本,也就刪除了這個目錄節點所有數據 ;獲取指定 path 下的所有子目錄節點,同樣 getChildren方法也有一個重載方法可以設置特定的 watcher 監控子節點的狀態
Stat setData(String path, byte[] data, int version)
byte[] getData(String path, boolean watch, Stat stat)
void addAuthInfo(String scheme, byte[] auth)
Stat setACL(String path, List acl, int version)
List getACL(String path, Stat stat)
給 path 設置數據,可以指定這個數據的版本號,如果 version 為 -1 怎可以匹配任何版本;獲取這個 path 對應的目錄節點存儲的數據,數據的版本等信息可以通過 stat 來指定,同時還可以設置是否監控這個目錄節點數據的狀態;客戶端將自己的授權信息提交給伺服器,伺服器將根據這個授權信息驗證客戶端的訪問許可權;給某個目錄節點重新設置訪問許可權,需要注意的是 Zookeeper 中的目錄節點許可權不具有傳遞性,父目錄節點的許可權不能傳遞給子目錄節點。目錄節點 ACL 由兩部分組成:perms 和 id。Perms 有 ALL、READ、WRITE、CREATE、DELETE、ADMIN 幾種 而 id 標識了訪問目錄節點的身份列表,默認情況下有以下兩種:ANYONE_ID_UNSAFE = new Id(「world」, 「anyone」) 和 AUTH_IDS = new Id(「auth」, 「」) 分別表示任何人都可以訪問和創建者擁有訪問許可權;獲取某個目錄節點的訪問許可權列表
學習最新熱門IT技術
找一份自己滿意的高薪工作
升職加薪就是它了
TAG:海文國際 |