Zookeeper不管是在實際項目中,仍是在各類分佈式開源項目中都獲得了普遍應用,從本篇博客開始,將爲你們帶來我對Zookeeper的認識。這個系列將會涵蓋Zookeeper的介紹、環境搭建、配置說明、Java操做Zookeeper(原生API方式)、zkclient操做Zookeeper方式、Zookeeper的典型應用場景分析以及Curator框架等。node
Zookeeper是一個高可用的分佈式管理與協調框架,基於ZAB算法(原子消息廣播協議)實現。ZK可以很好的保證分佈式環境下的數據一致性,這一特性使得ZK是處理分佈式一致性問題的利器!這個利器有哪些特性呢,看看下面你就瞭解了。算法
可靠性:一旦Zookeeper成功的應用了一個事務,並完成對client的響應,那麼Zookeeper內部集羣的全部服務器的狀態都會是一致的保留下來。服務器
單一視圖:因爲上面可靠性的保證,使得不管client鏈接的是ZK集羣中的哪一個服務器,所看到的數據都是一致的。session
順序一致性:從一個client發起的請求,最終會嚴格的按照發起的順序被應用到Zookeeper中去。【實質上,ZK會對每個client的每個請求,進行編號,說白了,就是分配一個全局惟一的遞增編號,這個編號反映了全部事務操做的前後順序。】數據結構
實時性:一般意義下的實時性是指一旦事務被成功應用,那麼client會馬上從服務器端獲取到變動後的新數據。ZK僅僅可以保證在必定時間內,client最終必定會能從服務器上獲取到最新的數據。app
高可用:在ZK集羣內部,會有一個Leader,多個Follower。一旦Leader掛掉,那麼ZK會經過Paxos算法選舉出新的Leader,只要ZK集羣內部的服務器有一半以上正常工做,那麼ZK就能對外正常提供服務!框架
簡單的數據結構:相似於Linux文件系統的樹形結構,簡單,實用!(樹形層次空間)分佈式
高性能:性能有多高呢,舉個栗子,好比咱們常常經過建立臨時節點來處理分佈式鎖,要知道臨時節點是存儲在內存中的,在讀場景壓力測試下,QPS高達10W+!也就是說ZK在讀場景下,性能很是突出!ide
每個節點被稱爲znode,znode能夠有子節點目錄,而且每一個znode能夠存儲數據(特別須要注意的是臨時節點不能夠有子節點)工具
znode若是是臨時節點,意味着建立這個znode的client一旦與ZK集羣失去聯繫,這個臨時的znode將被自動刪除。(事實上,client與ZK通訊是採用長鏈接方式,並經過心跳的方式保持鏈接,這種狀態就是session,一旦session失效,就是鏈接斷開,臨時節點會被刪除掉)
znode是能夠被監控的,不管是znode自己的數據變化,仍是該znode下的子節點的變化,均可以進行監控,這也是ZK的核心特性。(不少應用場景就是基於這個特性,後續進行詳細介紹)
這裏,咱們先了解下ZK Server的身份特性:
Leader:負責客戶端的write類型的請求
Follower:負責客戶端的read類型請求,並能夠參與Leader的選舉
watcher:後文介紹。
這裏以zookeeper-3.4.5版本爲例,搭建一個ZK集羣(至少要求3個節點,而且各個ZK SERVER之間系統時間保持一致)。使用的機器列表是:192.168.99.12一、192.168.99.12二、192.168.99.123。
以192.168.99.121爲例進行說明:
配置說明:
tickTime:ZK集羣與客戶端、ZK集羣內部SERVER之間的心跳間隔,默認2S。
initLimit:在客戶端鏈接ZK集羣時,能夠忍受多少個心跳次數。上述的配置代表,若是client初始鏈接ZK集羣,在10*2S=20S內ZK集羣沒有返回鏈接成功,即意味着鏈接失敗。
syncLimit:表示ZK集羣內部Leader和Follower之間請求應答能夠忍受多少個心跳次數。
dataDir:ZK保存數據以及日誌的目錄。
clientPort:ZK集羣對外暴露的接口,即client訪問ZK集羣的端口(2181)。
server.x = IP:port-a:port-b
X表示是第幾號服務器,從0開始編號,並和dataDir下的myid文件對應。
port-a表示Leader和Follower進行信息通訊的端口(2888)。
port-b表示Follower進行選舉的端口(3888)。
經過zkCli.sh進入客戶端進行操做:
查找ls、建立znode節點create(注意每一個節點都是有值的)、獲取get、設置set。
咱們觀察下下面幾個屬性:
ctime和cZxid是一對,表示建立ZNODE的時間和事件編號;
mtime和mZxid是一對,表示修改ZNODE數據內容的時間和事件編號;(經過set指令會改變這2個屬性,可是該節點的子節點的變化不會影響該節點)
dataVersion:表示ZNODE數據的版本,注意利用JAVA 原生API進行delete ZNODE時,須要提供version才能夠刪除ZNODE。(固然咱們能夠提供-1來跳過版本檢查機制)
dataLength、numChildren都好理解。
另外,注意rmr指令能夠遞歸刪除ZNODE;而delete只能夠刪除指定ZNODE。
ZooInspector是一個可運行的JAR,運行後直接鏈接ZK集羣中的任何一個SERVER便可。
OK,到這裏,一切準備工做就準備就緒了~
我們下期來看JAVA操做ZK(基於Zookeeper的原生API)、分佈式鎖探討、Watch特性等~