zookeeper介紹
zookeeper是一個爲分佈式應用提供一致性服務的軟件,它是開源的Hadoop項目中的一個子項目,而且根據google發表的<The Chubby lock service for loosely-coupled distributed systems>論文來實現的,接下來咱們首先來安裝使用下這個軟件,而後再來探索下其中比較重要一致性算法。
zookeeper安裝和使用
zookeeper的安裝基本上能夠按照 http://hadoop.apache.org/zookeeper/docs/current/ zookeeperStarted.html 這個頁面上的步驟完成安裝,這裏主要介紹下部署一個集羣的步驟,由於這個官方頁面彷佛講得並非很是詳細(Running Replicated Zookeeper)。
因爲手頭機器不足,因此在一臺機器上部署了3個server,若是你手頭也比較緊,也能夠這麼作。那麼我建了3個文件夾,以下
server1 server2 server3
而後每一個文件夾裏面解壓一個zookeeper的下載包,而且還建了幾個文件夾,整體結構以下,最後那個是下載過來壓縮包的解壓文件
data dataLog logs zookeeper-3.3.2
那麼首先進入data目錄,建立一個myid的文件,裏面寫入一個數字,好比我這個是server1,那麼就寫一個1,server2對應myid文件就寫入2,server3對應myid文件就寫個3
而後進入zookeeper-3.3.2/conf目錄,那麼若是是剛下過來,會有3個文件,configuration.xml, log4j.properties,zoo_sample.cfg,這3個文件咱們首先要作的就是在這個目錄建立一個zoo.cfg的配置文件,固然你能夠把zoo_sample.cfg文件改爲zoo.cfg,配置的內容以下所示:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=xxxx/zookeeper/server1/data
dataLogDir=xxx/zookeeper/server1/dataLog
clientPort=2181
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
標紅的幾個配置應該官網講得很清楚了,只是須要注意的是clientPort這個端口若是你是在1臺機器上部署多個server,那麼每臺機器都要不一樣的clientPort,好比我server1是2181,server2是2182,server3是2183,dataDir和dataLogDir也須要區分下。
最後幾行惟一須要注意的地方就是 server.X 這個數字就是對應 data/myid中的數字。你在3個server的myid文件中分別寫入了1,2,3,那麼每一個server中的zoo.cfg都配server.1,server.2,server.3就OK了。由於在同一臺機器上,後面連着的2個端口3個server都不要同樣,不然端口衝突,其中第一個端口用來集羣成員的信息交換,第二個端口是在leader掛掉時專門用來進行選舉leader所用。
進入zookeeper-3.3.2/bin 目錄中,./zkServer.sh start啓動一個server,這時會報大量錯誤?其實沒什麼關係,由於如今集羣只起了1臺server,zookeeper服務器端起來會根據zoo.cfg的服務器列表發起選舉leader的請求,由於連不上其餘機器而報錯,那麼當咱們起第二個zookeeper實例後,leader將會被選出,從而一致性服務開始可使用,這是由於3臺機器只要有2臺可用就能夠選出leader而且對外提供服務(2n+1臺機器,能夠容n臺機器掛掉)。
接下來就可使用了,咱們能夠先經過 zookeeper自帶的客戶端交互程序來簡單感覺下zookeeper到底作一些什麼事情。進入zookeeper-3.3.2/bin(3個server中任意一個)下,./zkCli.sh –server 127.0.0.1:2182,我連的是開着2182端口的機器。
那麼,首先咱們隨便打個命令,由於zookeeper不認識,他會給出命令的help,以下圖
ls(查看當前節點數據),
ls2(查看當前節點數據並能看到更新次數等數據) ,
create(建立一個節點) ,
get(獲得一個節點,包含數據和更新次數等數據),
set(修改節點)
delete(刪除一個節點)
經過上述命令實踐,咱們能夠發現,zookeeper使用了一個相似文件系統的樹結構,數據能夠掛在某個節點上,能夠對這個節點進行刪改。另外咱們還發現,當改動一個節點的時候,集羣中活着的機器都會更新到一致的數據。
zookeeper的數據模型
在簡單使用了zookeeper以後,咱們發現其數據模型有些像操做系統的文件結構,結構以下圖所示
(1) 每一個節點在zookeeper中叫作znode,而且其有一個惟一的路徑標識,如/SERVER2節點的標識就爲/APP3/SERVER2
(2) Znode能夠有子znode,而且znode裏能夠存數據,可是EPHEMERAL類型的節點不能有子節點
(3) Znode中的數據能夠有多個版本,好比某一個路徑下存有多個數據版本,那麼查詢這個路徑下的數據就須要帶上版本。
(4) znode 能夠是臨時節點,一旦建立這個 znode 的客戶端與服務器失去聯繫,這個 znode 也將自動刪除,Zookeeper 的客戶端和服務器通訊採用長鏈接方式,每一個客戶端和 服務器經過心跳來保持鏈接,這個鏈接狀態稱爲 session,若是 znode 是臨時節點,這個 session 失效,znode 也就刪除了
(5) znode 的目錄名能夠自動編號,如 App1 已經存在,再建立的話,將會自動命名爲 App2
(6) znode 能夠被監控,包括這個目錄節點中存儲的數據的修改,子節點目錄的變化等,一旦變化能夠通知設置監控的客戶端,這個功能是zookeeper對於應用最重要的特性,經過這個特性能夠實現的功能包括配置的集中管理,集羣管理,分佈式鎖等等。
經過java代碼使用zookeeper
Zookeeper的使用主要是經過建立其jar包下的Zookeeper實例,而且調用其接口方法進行的,主要的操做就是對znode的增刪改操做,監聽znode的變化以及處理。
如下爲主要的API使用和解釋html
Zookeeper的主流應用場景實現思路(除去官方示例)
(1)配置管理
集中式的配置管理在應用集羣中是很是常見的,通常商業公司內部都會實現一套集中的配置管理中心,應對不一樣的應用集羣對於共享各自配置的需求,而且在配置變動時可以通知到集羣中的每個機器。
Zookeeper很容易實現這種集中式的配置管理,好比將APP1的全部配置配置到/APP1 znode下,APP1全部機器一啓動就對/APP1這個節點進行監控(zk.exist("/APP1",true)),而且實現回調方法Watcher,那麼在zookeeper上/APP1 znode節點下數據發生變化的時候,每一個機器都會收到通知,Watcher方法將會被執行,那麼應用再取下數據便可(zk.getData("/APP1",false,null));
以上這個例子只是簡單的粗顆粒度配置監控,細顆粒度的數據能夠進行分層級監控,這一切都是能夠設計和控制的。 java
(2)集羣管理
應用集羣中,咱們經常須要讓每個機器知道集羣中(或依賴的其餘某一個集羣)哪些機器是活着的,而且在集羣機器由於宕機,網絡斷鏈等緣由可以不在人工介入的狀況下迅速通知到每個機器。
Zookeeper一樣很容易實現這個功能,好比我在zookeeper服務器端有一個znode叫/APP1SERVERS,那麼集羣中每個機器啓動的時候都去這個節點下建立一個EPHEMERAL類型的節點,好比server1建立/APP1SERVERS/SERVER1(可使用ip,保證不重複),server2建立/APP1SERVERS/SERVER2,而後SERVER1和SERVER2都watch /APP1SERVERS這個父節點,那麼也就是這個父節點下數據或者子節點變化都會通知對該節點進行watch的客戶端。由於EPHEMERAL類型節點有一個很重要的特性,就是客戶端和服務器端鏈接斷掉或者session過時就會使節點消失,那麼在某一個機器掛掉或者斷鏈的時候,其對應的節點就會消失,而後集羣中全部對/APP1SERVERS進行watch的客戶端都會收到通知,而後取得最新列表便可。
另外有一個應用場景就是集羣選master,一旦master掛掉可以立刻能從slave中選出一個master,實現步驟和前者同樣,只是機器在啓動的時候在APP1SERVERS建立的節點類型變爲EPHEMERAL_SEQUENTIAL類型,這樣每一個節點會自動被編號,例如 node
打印結果:[testChildPath10000000000, testChildPath20000000001, testChildPath40000000003, testChildPath30000000002]
算法
打印結果:[testChildPath2, testChildPath1, testChildPath4, testChildPath3]
咱們默認規定編號最小的爲master,因此當咱們對/APP1SERVERS節點作監控的時候,獲得服務器列表,只要全部集羣機器邏輯認爲最小編號節點爲master,那麼master就被選出,而這個master宕機的時候,相應的znode會消失,而後新的服務器列表就被推送到客戶端,而後每一個節點邏輯認爲最小編號節點爲master,這樣就作到動態master選舉。
總結 apache
咱們初步使用了一下zookeeper而且嘗試着描述了幾種應用場景的具體實現思路,接下來的文章,咱們會嘗試着去探究一下zookeeper的高可用性與leaderElection算法。服務器
參考:http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/網絡