1. 程式人生 > >Zookeeper分散式技術

Zookeeper分散式技術

1.CAP表示: 一致性(Consistency),可用性(Availability)和分割槽容錯性(Partition tolerance);

2.API概述
create /path data
建立一個名為/path的znode節點,幷包含資料data
delete /path
刪除一個名為/path的znode
exists /path
檢查是否存在一個名為/path的節點
setData /path data
設定名為/path的節點的資料為data
getData /path
獲取節點/path的節點資訊
getChildren /path
獲取節點/path下的所有子節點列表

當設定一個znode節點的資料或讀取時,znode節點的資料會被全部替換或讀取。

新建znode節點時,應當指定節點的型別,不同的節點的不同行為。znode有四種類型:持久的(persistent),臨時的(ephemeral),持久有序的(persistent-sequential),臨時有序的(ephemeral-sequential)。
持久的znode只能通過呼叫delete來刪除,臨時的znode節點,當建立該節點的客戶端崩潰或關閉和zookeeper的連線時,節點就會刪除。

3.監視和通知:
假定事件的發生順序:
1客戶端c1設定監控點來監控/task資料變化;
2客戶端c2連線後向/task新增新任務;
3客戶端c1接受到通知
4客戶端c1設定新的監控點,在設定完成前,第三個客戶端c3連線上來,向/task新增一個任務
客戶端c1設定了一個新的監控點,由c3新增的任務並沒有觸發通知。在設定監控點前,需要讀取節點的狀態,因此c1不會錯過任何變更。

對同一個znode操作,先向客戶端傳送通知,再對節點進行變更。

4.版本
每一個znode都有一個版本號,隨著每次資料變化而遞增。用來阻止並行操作的不一致性。

5.zookeeper架構
zookeeper伺服器端運行於兩種模式下:獨立模式和仲裁模式
仲裁模式下,有一組zookeeper伺服器,他們之間可以進行狀態的複製;如果讓一個客戶端等待每個伺服器完成資料儲存後再繼續,延遲問題就無法解決。
法定人數指zookeeper工作必須執行的伺服器的最少數量。法定人數的數量要保證不管系統發生延遲或崩潰,服務主動確認的任何更新請求需要保持下去,直到另一個請求代替它。

6.會話
對zookeeper集合執行任何請求前,一個客戶端必須和服務建立會話。
同一個會話的請求會以FIFO順序執行

7.第一個zookeeper會話
進入conf資料夾下將zoo_sample.cfg 複製一份命名為 zoo.cfg;
在zoo.cfg檔案中修改這個目錄的位置:dataDir=f:/users/me/zookeeper
啟動zkServer.cmd
啟動客戶端zkCli.cmd
要確認znode樹為空,除了節點/zookeeper外。
使用命令ls /
建立一個名為/workers的節點 create /workers “”
刪除節點delete /workers
退出zookeeper伺服器 quit

8.會話的狀態和生命週期
會話的狀態:connecting, connected, closed, not_connected
狀態的轉換依賴於發生在客戶端和服務之間的各種事件
一個會話從not_connected開始,客戶端初始化連線後,轉換到connecting,
成功建立連線,狀態轉換成connected,如果斷開連線或無響應,狀態轉換成connecting;會話過期或關閉會話,狀態轉換成closed
建立一個會話時,你需要設定會話超時這個重要的引數,這個引數 設定了ZooKeeper服務允許會話被宣告為超時之前存在的時間。

9.仲裁模式
可以在一個機器上執行多個伺服器,使用以下配置:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=f:/data/z1
clientPort=2181
server.1=127.0.0.1:2222:2223
server.2=127.0.0.1:3333:3334
server.3=127.0.0.1:4444:4445
將zookeeper檔案複製2份,配置修改dataDir=f:/data/z2 dataDir=f:/data/z3
clientPort=2182 clientPort=2183
在F盤下建立路徑data/z1, data/z2 , data/z3
並分別在路徑下建立檔案myid, 其中z1下的myid輸入1,z2下的myid輸入2,z3下的myid輸入3
相繼啟動zkServer.cmd, 開始會報錯,3個服務全部啟動後,就好了。

10.通過ZooKeeper實現鎖
每個程序p嘗試建立znode名為/lock, 如果成功建立znode表示它獲得了鎖並可以執行臨界區的程式碼。為了避免程序p崩潰導致鎖無法釋放,引發系統因死鎖而失靈,必須指定節點/lock為臨時節點。
其他程序因znode存在而建立/lock失敗。因此,程序監聽/lock的變化,並在檢測到/lock刪除時再次嘗試建立節點來獲得鎖。當收到/lock刪 除的通知時,如果程序p還需要繼續獲取鎖,它就繼續嘗試建立/lock的步驟,如果其他程序已經建立了,就繼續監聽節點。

11.一個主-從模式例子
主-從模式的模型中包括三個角色:
1主節點:主節點負責監視新的從節點和任務,分配任務給可用的從節點
2從節點:從節點會通過系統註冊自己,以確保主節點看到它們可以執行任
務,然後開始監視新任務。
3客戶端:客戶端建立新任務並等待系統的響應

主節點角色:
create -e /master "master1.example.com:2223
建立主節點的znode,以便獲得管理權。使用-e標誌來表示建立的 znode為臨時性的。
ls / 列出ZooKeeper樹的根。
get /master 獲取/master znode的元資料和資料。
再次嘗試建立 create -e /master “abc”
提示Node already exists: /master

為了檢測主節點可能發生的崩潰情況,需要在/master設定監視點。
stat /master true
建立/master的客戶端關閉 quit
另一個客戶端顯示WatchedEvent state:SyncConnected type:NodeDeleted path:/master
再次建立create -e /master “” 建立成功

建立三個 重要的父znode,/workers、/tasks和/assign:
create /workers “”
create /tasks “”
create /assign “”
在主節點上呼叫stat命令前,我們使用可選的true引數呼叫 ls命令。通過true這個引數,可以設定對應znode的子節點變化的監視點。
主節點(主客戶端)
ls /tasks
ls /workers
ls /assign
stat /tasks
stat / workers
stat /assign
從節點通過 在/workers子節點下建立臨時性的znode來進行通知,並在子節點中使用
主機名來標識自己:create -e /workers/worker1.example.com “worker1.example.com:2224
之前主節點已經監 視了/workers的子節點變化情況。一旦從節點在/workers下建立了一個 znode,主節點就會觀察到以下通知資訊:
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/workers

從節點需要建立一個父znode/assign/worker1.example.com 來接收任務分配,並通過第二個引數為true的ls命令來監視這個節點的變化,以便等待新的任務
create /assign/worker1.example.com “”
ls /assign/worker1.example.com true

開啟一個客戶端,建立一個任務
create -s /tasks/task- “cmd”
ls /tasks/task-0000000000 true
我們需要按照任務新增的順序來新增znode,其本質上為一個佇列。客戶端現在必須等待任務執行完畢。執行任務的從節點將任務執行 完畢後,會建立一個znode來表示任務狀態。客戶端通過檢視任務狀態 的znode是否建立來確定任務是否執行完畢,因此客戶端需要監視狀態 znode的建立事件。

一旦建立任務的znode,主節點會觀察到以下事件:
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks
主節點之後會檢查這個新的任務,獲取可用的從節點列表,之後分 配這個任務給worker1.example.com
create /assign/worker1.example.com/task-0000000000 “”
從節點接收到新任務分配的通知:
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/assign/worker1.example.com
從節點之後便開始檢查新任務,並確認該任務是否分配給自己:
ls /assign/worker1.example.com
一旦從節點完成任務的執行,它就會在/tasks中新增一個狀態 znode:
create /tasks/task-0000000000/status “done”
之後,客戶端接收到通知,並檢查執行結果:
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/tasks/task-0000000000
執行命令get /tasks/task-0000000000/status
看到任務成功執行,其狀態為“done”。