Zookeeper入門指南

Zookeeper是什么

官方文檔上這么解釋zookeeper,它是一個(gè)分布式服務(wù)框架,是Apache Hadoop 的一個(gè)子項(xiàng)目,它主要是用來(lái)解決分布式應(yīng)用中經(jīng)常遇到的一些數(shù)據(jù)管理問(wèn)題,如:統(tǒng)一命名服務(wù)、狀態(tài)同步服務(wù)、集群管理、分布式應(yīng)用配置項(xiàng)的管理等。

上面的解釋有點(diǎn)抽象,簡(jiǎn)單來(lái)說(shuō)zookeeper=文件系統(tǒng)+監(jiān)聽(tīng)通知機(jī)制

1 文件系統(tǒng)

Zookeeper維護(hù)一個(gè)類似文件系統(tǒng)的數(shù)據(jù)結(jié)構(gòu):

每個(gè)子目錄項(xiàng)如 NameService 都被稱作為 znode(目錄節(jié)點(diǎn)),和文件系統(tǒng)一樣,我們能夠自由的增加、刪除znode,在一個(gè)znode下增加、刪除子znode,唯一的不同在于znode是可以存儲(chǔ)數(shù)據(jù)的。

有四種類型的znode:

[if !supportLists]·???? [endif]PERSISTENT-持久化目錄節(jié)點(diǎn)

客戶端與zookeeper斷開(kāi)連接后,該節(jié)點(diǎn)依舊存在

[if !supportLists]·???? [endif]PERSISTENT_SEQUENTIAL-持久化順序編號(hào)目錄節(jié)點(diǎn)

客戶端與zookeeper斷開(kāi)連接后,該節(jié)點(diǎn)依舊存在,只是Zookeeper給該節(jié)點(diǎn)名稱進(jìn)行順序編號(hào)

[if !supportLists]·???? [endif]EPHEMERAL-臨時(shí)目錄節(jié)點(diǎn)

客戶端與zookeeper斷開(kāi)連接后,該節(jié)點(diǎn)被刪除

[if !supportLists]·???? [endif]EPHEMERAL_SEQUENTIAL-臨時(shí)順序編號(hào)目錄節(jié)點(diǎn)

客戶端與zookeeper斷開(kāi)連接后,該節(jié)點(diǎn)被刪除,只是Zookeeper給該節(jié)點(diǎn)名稱進(jìn)行順序編號(hào)

2 監(jiān)聽(tīng)通知機(jī)制

客戶端注冊(cè)監(jiān)聽(tīng)它關(guān)心的目錄節(jié)點(diǎn),當(dāng)目錄節(jié)點(diǎn)發(fā)生變化(數(shù)據(jù)改變、被刪除、子目錄節(jié)點(diǎn)增加刪除)時(shí),zookeeper會(huì)通知客戶端。

就這么簡(jiǎn)單,下面我們看看Zookeeper能做點(diǎn)什么呢?

Zookeeper能做什么

zookeeper功能非常強(qiáng)大,可以實(shí)現(xiàn)諸如分布式應(yīng)用配置管理、統(tǒng)一命名服務(wù)、狀態(tài)同步服務(wù)、集群管理等功能,我們這里拿比較簡(jiǎn)單的分布式應(yīng)用配置管理為例來(lái)說(shuō)明。

假設(shè)我們的程序是分布式部署在多臺(tái)機(jī)器上,如果我們要改變程序的配置文件,需要逐臺(tái)機(jī)器去修改,非常麻煩,現(xiàn)在把這些配置全部放到zookeeper上去,保存在 zookeeper 的某個(gè)目錄節(jié)點(diǎn)中,然后所有相關(guān)應(yīng)用程序?qū)@個(gè)目錄節(jié)點(diǎn)進(jìn)行監(jiān)聽(tīng),一旦配置信息發(fā)生變化,每個(gè)應(yīng)用程序就會(huì)收到 zookeeper 的通知,然后從 zookeeper 獲取新的配置信息應(yīng)用到系統(tǒng)中。

如上,你大致應(yīng)該了解zookeeper是個(gè)什么東西,大概能做些什么了,我們馬上來(lái)學(xué)習(xí)下zookeeper的安裝及使用,并開(kāi)發(fā)一個(gè)小程序來(lái)實(shí)現(xiàn)zookeeper這個(gè)分布式配置管理的功能。

Zookeeper單機(jī)模式安裝

Step1:配置JAVA環(huán)境,檢驗(yàn)環(huán)境:java -version

Step2:下載并解壓zookeeper

# cd /usr/local

# wgethttp://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz

# tar -zxvfzookeeper-3.4.12.tar.gz

# cdzookeeper-3.4.12

Step3:重命名配置文件zoo_sample.cfg

# cpconf/zoo_sample.cfg conf/zoo.cfg

Step4:?jiǎn)?dòng)zookeeper

#bin/zkServer.sh start

Step5:檢測(cè)是否成功啟動(dòng),用zookeeper客戶端連接下服務(wù)端

# bin/zkCli.sh

Zookeeper使用

使用客戶端命令操作zookeeper

1、使用 ls 命令來(lái)查看當(dāng)前 ZooKeeper 中所包含的內(nèi)容

2、創(chuàng)建一個(gè)新的 znode ,使用create /zkPro myData

3、再次使用 ls 命令來(lái)查看現(xiàn)在 zookeeper 中所包含的內(nèi)容:

4、下面我們運(yùn)行 get 命令來(lái)確認(rèn)第二步中所創(chuàng)建的 znode 是否包含我們所創(chuàng)建的字符串:

5、下面我們通過(guò) set 命令來(lái)對(duì) zk 所關(guān)聯(lián)的字符串進(jìn)行設(shè)置:

6、下面我們將剛才創(chuàng)建的 znode 刪除

使用Java API操作zookeeper

使用Java API操作zookeeper需要引用下面的包

下面我們來(lái)實(shí)現(xiàn)上面說(shuō)的分布式配置中心:

1、在zookeeper里增加一個(gè)目錄節(jié)點(diǎn),并且把配置信息存儲(chǔ)在里面

2、啟動(dòng)兩個(gè)zookeeper客戶端程序,代碼如下所示

importjava.util.concurrent.CountDownLatch;

importorg.apache.zookeeper.WatchedEvent;

importorg.apache.zookeeper.Watcher;

importorg.apache.zookeeper.Watcher.Event.EventType;

importorg.apache.zookeeper.Watcher.Event.KeeperState;

importorg.apache.zookeeper.ZooKeeper;

importorg.apache.zookeeper.data.Stat;

/**

?*分布式配置中心demo

?* @author

?*

?*/

public class ZooKeeperProSync implements Watcher {

??? private static CountDownLatch connectedSemaphore = new CountDownLatch(1);

??? private static ZooKeeper zk = null;

??? private static Stat stat = newStat();

??? public static void main(String[] args) throws Exception {

??????? //zookeeper配置數(shù)據(jù)存放路徑

??????? String path ="/username";

??????? //連接zookeeper并且注冊(cè)一個(gè)默認(rèn)的監(jiān)聽(tīng)器

??????? zk =new ZooKeeper("192.168.31.100:2181", 5000, //

??????????????? newZooKeeperProSync());

??????? //等待zk連接成功的通知

??????? connectedSemaphore.await();

??????? //獲取path目錄節(jié)點(diǎn)的配置數(shù)據(jù),并注冊(cè)默認(rèn)的監(jiān)聽(tīng)器

??????? System.out.println(new String(zk.getData(path, true, stat)));

???????Thread.sleep(Integer.MAX_VALUE);

??? }

??? public void process(WatchedEvent event) {

??????? if(KeeperState.SyncConnected == event.getState()) {? //zk連接成功通知事件

??????????? if (EventType.None == event.getType() && null== event.getPath()) {

???????????????connectedSemaphore.countDown();

??????????? }else if(event.getType() ==EventType.NodeDataChanged) {? //zk目錄節(jié)點(diǎn)數(shù)據(jù)變化通知事件

??????????????? try{

???????????????????System.out.println("配置已修改,新值為:" + newString(zk.getData(event.getPath(), true, stat)));

??????????????? }catch(Exception e) {

??????????????? }

??????????? }

??????? }

??? }

}

兩個(gè)程序啟動(dòng)后都正確的讀取到了zookeeper的/username目錄節(jié)點(diǎn)下的數(shù)據(jù)'qingfeng'

3、我們?cè)趜ookeeper里修改下目錄節(jié)點(diǎn)/username下的數(shù)據(jù)

修改完成后,我們看見(jiàn)兩個(gè)程序后臺(tái)都及時(shí)收到了他們監(jiān)聽(tīng)的目錄節(jié)點(diǎn)數(shù)據(jù)變更后的值,如下所示

[if !vml]

[endif]

Zookeeper集群模式安裝

本例搭建的是偽集群模式,即一臺(tái)機(jī)器上啟動(dòng)三個(gè)zookeeper實(shí)例組成集群,真正的集群模式無(wú)非就是實(shí)例IP地址不同,搭建方法沒(méi)有區(qū)別

Step1:配置JAVA環(huán)境,檢驗(yàn)環(huán)境:java -version

Step2:下載并解壓zookeeper

# cd /usr/local

# wgethttp://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz

# tar -zxvfzookeeper-3.4.12.tar.gz

# cdzookeeper-3.4.12

Step3:重命名 zoo_sample.cfg文件

# cpconf/zoo_sample.cfg conf/zoo-1.cfg

Step4:修改配置文件zoo-1.cfg,原配置文件里有的,修改成下面的值,沒(méi)有的則加上

# vimconf/zoo-1.cfg

dataDir=/tmp/zookeeper-1

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

配置說(shuō)明

[if !supportLists]·????[endif]tickTime:這個(gè)時(shí)間是作為 Zookeeper 服務(wù)器之間或客戶端與服務(wù)器之間維持心跳的時(shí)間間隔,也就是每個(gè) tickTime 時(shí)間就會(huì)發(fā)送一個(gè)心跳。

[if !supportLists]·????[endif]initLimit:這個(gè)配置項(xiàng)是用來(lái)配置 Zookeeper 接受客戶端(這里所說(shuō)的客戶端不是用戶連接 Zookeeper 服務(wù)器的客戶端,而是 Zookeeper 服務(wù)器集群中連接到 Leader 的 Follower 服務(wù)器)初始化連接時(shí)最長(zhǎng)能忍受多少個(gè)心跳時(shí)間間隔數(shù)。當(dāng)已經(jīng)超過(guò) 10個(gè)心跳的時(shí)間(也就是 tickTime)長(zhǎng)度后 Zookeeper 服務(wù)器還沒(méi)有收到客戶端的返回信息,那么表明這個(gè)客戶端連接失敗。總的時(shí)間長(zhǎng)度就是 10*2000=20 秒

[if !supportLists]·????[endif]syncLimit:這個(gè)配置項(xiàng)標(biāo)識(shí) Leader 與 Follower 之間發(fā)送消息,請(qǐng)求和應(yīng)答時(shí)間長(zhǎng)度,最長(zhǎng)不能超過(guò)多少個(gè) tickTime 的時(shí)間長(zhǎng)度,總的時(shí)間長(zhǎng)度就是 5*2000=10秒

[if !supportLists]·????[endif]dataDir:顧名思義就是 Zookeeper 保存數(shù)據(jù)的目錄,默認(rèn)情況下,Zookeeper 將寫數(shù)據(jù)的日志文件也保存在這個(gè)目錄里。

[if !supportLists]·????[endif]clientPort:這個(gè)端口就是客戶端連接 Zookeeper 服務(wù)器的端口,Zookeeper 會(huì)監(jiān)聽(tīng)這個(gè)端口,接受客戶端的訪問(wèn)請(qǐng)求。

[if !supportLists]·????[endif]server.A=B:C:D:其中 A 是一個(gè)數(shù)字,表示這個(gè)是第幾號(hào)服務(wù)器;B 是這個(gè)服務(wù)器的 ip 地址;C 表示的是這個(gè)服務(wù)器與集群中的 Leader 服務(wù)器交換信息的端口;D 表示的是萬(wàn)一集群中的 Leader 服務(wù)器掛了,需要一個(gè)端口來(lái)重新進(jìn)行選舉,選出一個(gè)新的 Leader,而這個(gè)端口就是用來(lái)執(zhí)行選舉時(shí)服務(wù)器相互通信的端口。如果是偽集群的配置方式,由于 B 都是一樣,所以不同的 Zookeeper 實(shí)例通信端口號(hào)不能一樣,所以要給它們分配不同的端口號(hào)。

Step4:再?gòu)膠oo-1.cfg復(fù)制兩個(gè)配置文件zoo-2.cfg和zoo-3.cfg,只需修改dataDir和clientPort不同即可

# cpconf/zoo-1.cfg conf/zoo-2.cfg

# cpconf/zoo-1.cfg conf/zoo-3.cfg

# vimconf/zoo-2.cfg

dataDir=/tmp/zookeeper-2

clientPort=2182

# vimconf/zoo-2.cfg

dataDir=/tmp/zookeeper-3

clientPort=2183

Step5:標(biāo)識(shí)Server ID

創(chuàng)建三個(gè)文件夾/tmp/zookeeper-1,/tmp/zookeeper-2,/tmp/zookeeper-2,在每個(gè)目錄中創(chuàng)建文件myid 文件,寫入當(dāng)前實(shí)例的server id,即1.2.3

# cd/tmp/zookeeper-1

# vim myid

1

# cd/tmp/zookeeper-2

# vim myid

2

# cd/tmp/zookeeper-3

# vim myid

3

Step6:?jiǎn)?dòng)三個(gè)zookeeper實(shí)例

#bin/zkServer.sh start conf/zoo-1.cfg

#bin/zkServer.sh start conf/zoo-2.cfg

#bin/zkServer.sh start conf/zoo-3.cfg

Step7:檢測(cè)集群狀態(tài),也可以直接用命令“zkCli.sh -server IP:PORT”連接zookeeper服務(wù)端檢測(cè)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,001評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,786評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 176,986評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,204評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,964評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,354評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,410評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 42,554評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,106評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,918評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,093評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,648評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,342評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 34,755評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 36,009評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,839評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,107評(píng)論 2 375