Zookeeper是什么?想必馬上想到的是一般在集群中監(jiān)控集群的。那么zookeeper到底是什么?
ZooKeeper是用來保證數(shù)據(jù)在集群間的事務性一致。
Zookeeper提供了什么?
zookeeper=文件系統(tǒng)+通知機制
1.Zookeeper虛擬文件系統(tǒng)
Zookeeper維護一個類似文件系統(tǒng)的數(shù)據(jù)結構

每個子目錄項如 NameService 都被稱作為 znode,和文件系統(tǒng)一樣,我們能夠自由的增加、刪除znode,在一個znode下增加、刪除子znode,唯一的不同在于znode是可以存儲數(shù)據(jù)的。
有四種類型的znode:
1、PERSISTENT-持久化目錄節(jié)點
客戶端與zookeeper斷開連接后,該節(jié)點依舊存在
2、 PERSISTENT_SEQUENTIAL-持久化順序編號目錄節(jié)點
客戶端與zookeeper斷開連接后,該節(jié)點依舊存在,只是Zookeeper給該節(jié)點名稱進行順序編號
3、EPHEMERAL-臨時目錄節(jié)點
客戶端與zookeeper斷開連接后,該節(jié)點被刪除
4、EPHEMERAL_SEQUENTIAL-臨時順序編號目錄節(jié)點
客戶端與zookeeper斷開連接后,該節(jié)點被刪除,只是Zookeeper給該節(jié)點名稱進行順序編號
2、通知機制
客戶端注冊監(jiān)聽它關心的目錄節(jié)點,當目錄節(jié)點發(fā)生變化(數(shù)據(jù)改變、被刪除、子目錄節(jié)點增加刪除)時,zookeeper會通知客戶端。
事件的監(jiān)聽機制。
當我們想在ZooKeeper中建立節(jié)點、刪除節(jié)點、修改節(jié)點值等時候,都會產生事件,注冊了事件監(jiān)聽器的類,就可以獲得這些事件。換句話說,只要ZooKeeper的節(jié)點變化了,那么數(shù)據(jù)肯定變化,那么注冊器通過監(jiān)控節(jié)點的變化就可以知道數(shù)據(jù)的變化。那么而這正是Zookeeper的無比強大之處。
Zk中數(shù)據(jù)的通知機制是通過對節(jié)點變化的監(jiān)聽機制實現(xiàn)的。
Zookeeper選舉制度舉例
Zookeeper的核心是原子廣播,這個機制保證了各個Server之間的同步。實現(xiàn)這個機制的協(xié)議叫做Zab協(xié)議。Zab協(xié)議有兩種模式,它們分 別是恢復模式(選主)和廣播模式(同步)。當服務啟動或者在領導者崩潰后,Zab就進入了恢復模式,當領導者被選舉出來,且大多數(shù)Server完成了和 leader的狀態(tài)同步以后,恢復模式就結束了。狀態(tài)同步保證了leader和Server具有相同的系統(tǒng)狀態(tài)。
為了保證事務的順序一致性,zookeeper采用了遞增的事務id號(zxid)來標識事務。所有的提議(proposal)都在被提出的時候加上 了zxid。實現(xiàn)中zxid是一個64位的數(shù)字,它高32位是epoch用來標識leader關系是否改變,每次一個leader被選出來,它都會有一個 新的epoch,標識當前屬于那個leader的統(tǒng)治時期。低32位用于遞增計數(shù)。
每個Server在工作過程中有三種狀態(tài):
LOOKING:當前Server不知道leader是誰,正在搜尋
LEADING:當前Server即為選舉出來的leader
FOLLOWING:leader已經選舉出來,當前Server與之同步
目前有5臺服務器,每臺服務器均沒有數(shù)據(jù),它們的編號分別是1,2,3,4,5,按編號依次啟動,它們的選擇舉過程如下:
- 服務器1啟動,給自己投票,然后發(fā)投票信息,由于其它機器還沒有啟動所以它收不到反饋信息,服務器1的狀態(tài)一直屬于Looking。
- 服務器2啟動,給自己投票,同時與之前啟動的服務器1交換結果,由于服務器2的編號大所以服務器2勝出,但此時投票數(shù)沒有大于半數(shù),所以兩個服務器的狀態(tài)依然是LOOKING。
- 服務器3啟動,給自己投票,同時與之前啟動的服務器1,2交換信息,由于服務器3的編號最大所以服務器3勝出,此時投票數(shù)正好大于半數(shù),所以服務器3成為領導者,服務器1,2成為小弟。
- 服務器4啟動,給自己投票,同時與之前啟動的服務器1,2,3交換信息,盡管服務器4的編號大,但之前服務器3已經勝出,所以服務器4只能成為小弟。
- 服務器5啟動,后面的邏輯同服務器4成為小弟。
用Zookeeper做什么?
1.命名服務
在zookeeper的文件系統(tǒng)里創(chuàng)建一個目錄,即有唯一的path。在我們使用tborg無法確定上游程序的部署機器時即可與下游程序約定好path,通過path即能互相探索發(fā)現(xiàn)。
2.配置管理
程序總是需要配置的,如果程序分散部署在多臺機器上,要逐個改變配置就變得困難。好吧,現(xiàn)在把這些配置全部放到zookeeper上去,保存在 Zookeeper 的某個目錄節(jié)點中,然后所有相關應用程序對這個目錄節(jié)點進行監(jiān)聽,一旦配置信息發(fā)生變化,每個應用程序就會收到 Zookeeper 的通知,然后從 Zookeeper 獲取新的配置信息應用到系統(tǒng)中就好。
3.集群管理
所謂集群管理無在乎兩點:是否有機器退出和加入、選舉master。
對于第一點,所有機器約定在父目錄GroupMembers下創(chuàng)建臨時目錄節(jié)點,然后監(jiān)聽父目錄節(jié)點的子節(jié)點變化消息。一旦有機器掛掉,該機器與zookeeper的連接斷開,其所創(chuàng)建的臨時目錄節(jié)點被刪除,所有其他機器都收到通知:某個兄弟目錄被刪除,于是,所有人都知道:它上船了。新機器加入也是類似,所有機器收到通知:新兄弟目錄加入,highcount又有了。
對于第二點,我們稍微改變一下,所有機器創(chuàng)建臨時順序編號目錄節(jié)點,每次選取編號最小的機器作為master就好。
4.分布式鎖
有了zookeeper的一致性文件系統(tǒng),鎖的問題變得容易。鎖服務可以分為兩類,一個是保持獨占,另一個是控制時序。
對于第一類,我們將zookeeper上的一個znode看作是一把鎖,通過createznode的方式來實現(xiàn)。所有客戶端都去創(chuàng)建 /distribute_lock 節(jié)點,最終成功創(chuàng)建的那個客戶端也即擁有了這把鎖。廁所有言:來也沖沖,去也沖沖,用完刪除掉自己創(chuàng)建的distribute_lock 節(jié)點就釋放出鎖。
對于第二類, /distribute_lock 已經預先存在,所有客戶端在它下面創(chuàng)建臨時順序編號目錄節(jié)點,和選master一樣,編號最小的獲得鎖,用完刪除,依次方便。
5.隊列管理
兩種類型的隊列:
1、 同步隊列,當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達。
2、隊列按照 FIFO 方式進行入隊和出隊操作。
第一類,在約定目錄下創(chuàng)建臨時目錄節(jié)點,監(jiān)聽節(jié)點數(shù)目是否是我們要求的數(shù)目。
第二類,和分布式鎖服務中的控制時序場景基本原理一致,入列有編號,出列按編號。
分布式與數(shù)據(jù)復制
Zookeeper作為一個集群提供一致的數(shù)據(jù)服務,自然,它要在所有機器間做數(shù)據(jù)復制。數(shù)據(jù)復制的好處:
- 1、 容錯
一個節(jié)點出錯,不致于讓整個系統(tǒng)停止工作,別的節(jié)點可以接管它的工作; - 2、提高系統(tǒng)的擴展能力
把負載分布到多個節(jié)點上,或者增加節(jié)點來提高系統(tǒng)的負載能力; - 3、提高性能
讓客戶端本地訪問就近的節(jié)點,提高用戶訪問速度。
從客戶端讀寫訪問的透明度來看,數(shù)據(jù)復制集群系統(tǒng)分下面兩種:
1、寫主(WriteMaster)
對數(shù)據(jù)的修改提交給指定的節(jié)點。讀無此限制,可以讀取任何一個節(jié)點。這種情況下客戶端需要對讀與寫進行區(qū)別,俗稱讀寫分離;
2、寫任意(Write Any)
對數(shù)據(jù)的修改可提交給任意的節(jié)點,跟讀一樣。這種情況下,客戶端對集群節(jié)點的角色與變化透明。
對zookeeper來說,它采用的方式是寫任意。通過增加機器,它的讀吞吐能力和響應能力擴展性非常好,而寫,隨著機器的增多吞吐能力肯定下降(這也是它建立observer的原因),而響應能力則取決于具體實現(xiàn)方式,是延遲復制保持最終一致性,還是立即復制快速響應。
我們關注的重點還是在如何保證數(shù)據(jù)在集群所有機器的一致性,這就涉及到paxos算法。
Zookeeper中的角色
