Zookeeper應(yīng)用介紹與安裝部署

1 Zookeeper概述#

ZooKeeper是一個為分布式應(yīng)用所設(shè)計的分布的劫映、開源的協(xié)調(diào)服務(wù)乓旗,它主要是用來解決分布式應(yīng)用中經(jīng)常遇到的一些數(shù)據(jù)管理問題府蛇,簡化分布式應(yīng)用協(xié)調(diào)及其管理的難度,提供高性能的分布式服務(wù)屿愚。ZooKeeper本身可以以Standalone模式安裝運行汇跨,不過它的長處在于通過分布式ZooKeeper集群(一個Leader,多個Follower)妆距,基于一定的策略來保證ZooKeeper集群的穩(wěn)定性和可用性穷遂,從而實現(xiàn)分布式應(yīng)用的可靠性

在網(wǎng)上看到了一個很不錯的關(guān)于ZooKeeper的介紹: 顧名思義動物園管理員娱据,他是拿來管大象(Hadoop) 蚪黑、 蜜蜂(Hive) 、 小豬(Pig) 的管理員吸耿, Apache Hbase和 Apache Solr 以及LinkedIn sensei 等項目中都采用到了 Zookeeper祠锣。ZooKeeper是一個分布式的酷窥,開放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù)咽安,ZooKeeper是以Fast Paxos算法為基礎(chǔ),實現(xiàn)同步服務(wù)蓬推,配置維護和命名服務(wù)等分布式應(yīng)用妆棒。

從介紹可以看出,ZooKeeper更傾向于對大型應(yīng)用的協(xié)同維護管理工作沸伏。IBM則給出了IBM對ZooKeeper的認知: Zookeeper 分布式服務(wù)框架是 Apache Hadoop 的一個子項目糕珊,它主要是用來解決分布式應(yīng)用中經(jīng)常遇到的一些數(shù)據(jù)管理問題,如:統(tǒng)一命名服務(wù)毅糟、狀態(tài)同步服務(wù)红选、集群管理、分布式應(yīng)用配置項的管理等姆另。

總之喇肋,我認為它的核心詞就是一個單詞,協(xié)調(diào)迹辐。

2 Zookeeper特征#

在Hadoop權(quán)威指南中看到了關(guān)于ZooKeeper的一些核心特征蝶防,閱讀之后感覺總結(jié)的甚是精辟,在這里引用并總結(jié)明吩。

2.1 簡易##

ZooKeeper的最重要核心就是一個精簡文件系統(tǒng)间学,提供一些簡單的操作以及附加的抽象(例如排序和通知)。

2.2 易表達##

ZooKeeper的原型是一個豐富的集合,它們是一些已建好的塊低葫,可以用來構(gòu)建大型的協(xié)作數(shù)據(jù)結(jié)構(gòu)和協(xié)議详羡,例如:分布式隊列、分布式鎖以及一組對等體的選舉嘿悬。

2.3 高可用性##

ZooKeeper運行在一些集群上殷绍,被設(shè)計成可用性較高的,因此應(yīng)用程序可以依賴它鹊漠。ZooKeeper可以幫助你的系統(tǒng)避免單點故障主到,從而建立一個可靠的應(yīng)用程序

2.4 松散耦合##

ZooKeeper的交互支持參與者之間并不了解對方躯概。例如:ZooKeeper可以被當(dāng)做一種公共的機制登钥,使得進程彼此不知道對方的存在也可以相互發(fā)現(xiàn)并且交互,對等方可能甚至不是同步的娶靡。

這一特點我感覺最能體現(xiàn)在集群的部署啟動過程中牧牢。像Hadoop當(dāng)把配置文件寫好之后,然后運行啟動腳本姿锭,則251塔鳍,241,242中作為集群的虛擬機是同步啟動的呻此,也就是DataNode轮纫,NameNode,TaskTracker焚鲜,以及JobTracker的啟動并運行時在一次啟動過程中啟動的掌唾,就是運行一次啟動腳本文件,則都啟動起來忿磅。但是ZooKeeper的啟動過程卻不是這樣的糯彬。我在251,241葱她,242部署了ZooKeeper集群撩扒,并進行啟動,則啟動的過程是這樣的:首先ssh到251然后啟動吨些,這時候251的集群節(jié)點啟動起來搓谆,但是控制臺一直報錯,大概的含義就是沒有檢測到其他兩個結(jié)點锤灿。接著分別ssh到241挽拔,242,分別啟動集群中的剩下的結(jié)點但校,當(dāng)241啟動起來時螃诅,回到251查看,發(fā)現(xiàn)報錯的信息減少,意思是只差一個結(jié)點术裸。當(dāng)251倘是,241,242三臺服務(wù)器的結(jié)點全部啟動起來袭艺,則三臺的服務(wù)器的控制臺打印出正常的信息搀崭。

2.5 一個庫##

ZooKeeper提供了一個開源的、共享的執(zhí)行存儲猾编,以及通用協(xié)作的方法瘤睹,分擔(dān)了每個程序員寫通用協(xié)議的負擔(dān)。隨著時間的推移答倡,人們可以增加和改進這個庫來滿足自己的需求轰传。

3 為什么使用Zookeeper#

記得在大約在2006年的時候Google出了Chubby來解決分布一致性的問題(distributed consensus problem),所有集群中的服務(wù)器通過Chubby最終選出一個Master Server 瘪撇,最后這個Master Server來協(xié)調(diào)工作获茬。簡單來說其原理就是:在一個分布式系統(tǒng)中,有一組服務(wù)器在運行同樣的程序倔既,它們需要確定一個Value恕曲,以那個服務(wù)器提供的信息為主/為準(zhǔn),當(dāng)這個服務(wù)器經(jīng)過n/2+1的方式被選出來后渤涌,所有的機器上的Process都會被通知到這個服務(wù)器就是主服務(wù)器 Master服務(wù)器佩谣,大家以他提供的信息為準(zhǔn)。很想知道Google Chubby中的奧妙歼捏,可惜人家Google不開源稿存,自家用。

但是在2009年3年以后沉默已久的Yahoo在Apache上推出了類似的產(chǎn)品ZooKeeper瞳秽,并且在Google原有Chubby的設(shè)計思想上做了一些改進,因為ZooKeeper并不是完全遵循Paxos協(xié)議率翅,而是基于自身設(shè)計并優(yōu)化的一個2 phase commit的協(xié)議练俐,如圖所示:

image.png

ZooKeeper跟Chubby一樣用來存放一些相互協(xié)作的信息(Coordination),這些信息比較小一般不會超過1M冕臭,在zookeeper中是以一種hierarchical tree的形式來存放腺晾,這些具體的Key/Value信息就store在tree node中

當(dāng)有事件導(dǎo)致node數(shù)據(jù)辜贵,例如:變更悯蝉,增加,刪除時托慨,Zookeeper就會調(diào)用 triggerWatch方法鼻由,判斷當(dāng)前的path來是否有對應(yīng)的監(jiān)聽者(watcher),如果有watcher,會觸發(fā)其process方法,執(zhí)行process方法中的業(yè)務(wù)邏輯蕉世,如圖:

image.png

3.1 應(yīng)用實例##

ZooKeeper有了上述的這些用途蔼紧,讓我們設(shè)想一下,在一個分布式系統(tǒng)中有這這樣的一個應(yīng)用:

2個任務(wù)工廠(Task Factory)一主一從狠轻,如果從的發(fā)現(xiàn)主的死了以后奸例,從的就開始工作,他的工作就是向下面很多臺代理(Agent)發(fā)送指令向楼,讓每臺代理(Agent)獲得不同的賬戶進行分布式并行計算查吊,而每臺代理(Agent)中將分配很多帳號,如果其中一臺代理(Agent)死掉了湖蜕,那么這臺死掉的代理上的賬戶就不會繼續(xù)工作了菩貌。上述,出現(xiàn)了3個最主要的問題:

  1. Task Factory 主/從一致性的問題重荠;
  2. Task Factory 主/從心跳如何用簡單+穩(wěn)定 或者2者折中的方式實現(xiàn)箭阶;
  3. 一臺代理(Agent)死掉了以后,一部分的賬戶就無法繼續(xù)工作戈鲁,需要通知所有在線的代理(Agent)重新分配一次帳號仇参;
image.png

OK,讓我們想想ZooKeeper是不是能幫助我們?nèi)ソ鉀Q目前遇到的這3個最主要的問題呢婆殿?

  1. 任務(wù)工廠Task Factory都連接到ZooKeeper上诈乒,創(chuàng)建節(jié)點,設(shè)置對這個節(jié)點進行監(jiān)控婆芦,監(jiān)控方法例如:
event= new WatchedEvent(EventType.NodeDeleted, KeeperState.SyncConnected, "/TaskFactory");

這個方法的意思就是只要Task Factory與zookeeper斷開連接后怕磨,這個節(jié)點就會被自動刪除

  1. 原來主的任務(wù)工廠斷開了TCP連接消约,這個被創(chuàng)建的/TaskFactory節(jié)點就不存在了肠鲫,而且另外一個連接在上面的Task Factory可以立刻收到這個事件(Event),知道這個節(jié)點不存在了或粮,也就是說主TaskFactory死了导饲。

  2. 接下來另外一個活著的TaskFactory會再次創(chuàng)建/TaskFactory節(jié)點,并且寫入自己的ip到znode里面氯材,作為新的標(biāo)記渣锦。

  3. 此時Agents也會知道主的TaskFactory不工作了,為了防止系統(tǒng)中大量的拋出異常氢哮,他們將會先把自己手上的事情做完袋毙,然后掛起,等待收到Zookeeper上重新創(chuàng)建一個/TaskFactory節(jié)點冗尤,收到 EventType.NodeCreated 類型的事件將會繼續(xù)工作听盖。

  4. 原來從的TaskFactory 將自己變成一個主TaskFactory胀溺,當(dāng)系統(tǒng)管理員啟動原來死掉的主的TaskFactory,世界又恢復(fù)平靜了媳溺。

  5. 如果一臺代理死掉月幌,其他代理他們將會先把自己手上的事情做完,然后掛起悬蔽,向TaskFactory發(fā)送請求扯躺,TaskFactory會重新分配(sharding)帳戶到每個Agent上了,繼續(xù)工作蝎困。

上述內(nèi)容录语,大致如圖所示:


image.png

4 Zookeeper基本知識#

4.1 層次化的名字空間##

ZooKeeper的整個名字空間的結(jié)構(gòu)是層次化的,和一般的Linux文件系統(tǒng)結(jié)構(gòu)非常相似禾乘,一顆很大的樹澎埠。這也就是ZooKeeper的數(shù)據(jù)結(jié)構(gòu)情況。名字空間的層次由斜杠/來進行分割始藕,在名稱空間里面的每一個結(jié)點的名字空間唯一由這個結(jié)點的路徑來確定蒲稳。

每一個節(jié)點擁有自身的一些信息,包括:數(shù)據(jù)伍派、數(shù)據(jù)長度江耀、創(chuàng)建時間、修改時間等等诉植。從這樣一類既含有數(shù)據(jù)祥国,又作為路徑表標(biāo)示的節(jié)點的特點中,可以看出晾腔,ZooKeeper的節(jié)點既可以被看做是一個文件舌稀,又可以被看做是一個目錄,它同時具有二者的特點灼擂。為了便于表達壁查,今后我們將使用Znode來表示所討論的ZooKeeper節(jié)點

4.2 Znode##

Znode維護著數(shù)據(jù)缤至、ACL(access control list潮罪,訪問控制列表)、時間戳等交換版本號等數(shù)據(jù)結(jié)構(gòu)领斥,它通過對這些數(shù)據(jù)的管理來讓緩存生效并且令協(xié)調(diào)更新。每當(dāng)Znode中的數(shù)據(jù)更新后它所維護的版本號將增加沃暗,這非常類似于數(shù)據(jù)庫中計數(shù)器時間戳的操作方式月洛。

另外Znode還具有原子性操作的特點:命名空間中,每一個Znode的數(shù)據(jù)將被原子地讀寫孽锥。讀操作將讀取與Znode相關(guān)的所有數(shù)據(jù)嚼黔,寫操作將替換掉所有的數(shù)據(jù)细层。除此之外,每一個節(jié)點都有一個訪問控制列表唬涧,這個訪問控制列表規(guī)定了用戶操作的權(quán)限疫赎。

ZooKeeper中同樣存在臨時節(jié)點。這些節(jié)點與session同時存在碎节,當(dāng)session生命周期結(jié)束捧搞,這些臨時節(jié)點也將被刪除。臨時節(jié)點在某些場合也發(fā)揮著非常重要的作用狮荔。

4.3 Watch機制##

Watch機制就和單詞本身的意思一樣胎撇,看≈呈希看什么晚树?具體來講就是某一個或者一些Znode的變化。官方給出的定義:一個Watch事件是一個一次性的觸發(fā)器雅采,當(dāng)被設(shè)置了Watch的數(shù)據(jù)發(fā)生了改變的時候爵憎,則服務(wù)器將這個改變發(fā)送給設(shè)置了Watch的客戶端,以便通知它們婚瓜。

Watch機制主要有以下三個特點:

  1. 一次性的觸發(fā)器(one-time trigger)

當(dāng)數(shù)據(jù)改變的時候宝鼓,那么一個Watch事件會產(chǎn)生并且被發(fā)送到客戶端中。但是客戶端只會收到一次這樣的通知闰渔,如果以后這個數(shù)據(jù)再次發(fā)生改變的時候席函,之前設(shè)置Watch的客戶端將不會再次收到改變的通知,因為Watch機制規(guī)定了它是一個一次性的觸發(fā)器冈涧。

當(dāng)設(shè)置監(jiān)視的數(shù)據(jù)發(fā)生改變時茂附,該監(jiān)視事件會被發(fā)送到客戶端,例如督弓,如果客戶端調(diào)用了 getData("/znode1", true) 并且稍后 /znode1 節(jié)點上的數(shù)據(jù)發(fā)生了改變或者被刪除了营曼,客戶端將會獲取到 /znode1 發(fā)生變化的監(jiān)視事件,而如果 /znode1 再一次發(fā)生了變化愚隧,除非客戶端再次對 /znode1 設(shè)置監(jiān)視蒂阱,否則客戶端不會收到事件通知

  1. 發(fā)送給客戶端(Sent to the client)

這個表明了Watch的通知事件是從服務(wù)器發(fā)送給客戶端的狂塘,是異步的录煤,這就表明不同的客戶端收到的Watch的時間可能不同,但是ZooKeeper有保證:當(dāng)一個客戶端在看到Watch事件之前是不會看到結(jié)點數(shù)據(jù)的變化的荞胡。例如:A=3妈踊,此時在上面設(shè)置了一次Watch,如果A突然變成4了泪漂,那么客戶端會先收到Watch事件的通知廊营,然后才會看到A=4歪泳。

Zookeeper 客戶端和服務(wù)端是通過 Socket 進行通信的,由于網(wǎng)絡(luò)存在故障露筒,所以監(jiān)視事件很有可能不會成功地到達客戶端呐伞,監(jiān)視事件是異步發(fā)送至監(jiān)視者的,Zookeeper 本身提供了保序性(ordering guarantee):即客戶端只有首先看到了監(jiān)視事件后慎式,才會感知到它所設(shè)置監(jiān)視的 znode 發(fā)生了變化(a client will never see a change for which it has set a watch until it first sees the watch event). 網(wǎng)絡(luò)延遲或者其他因素可能導(dǎo)致不同的客戶端在不同的時刻感知某一監(jiān)視事件伶氢,但是不同的客戶端所看到的一切具有一致的順序

  1. 被設(shè)置Watch的數(shù)據(jù)(The data for which the watch was set)

這意味著 znode 節(jié)點本身具有不同的改變方式瞬捕。你也可以想象 Zookeeper 維護了兩條監(jiān)視鏈表:數(shù)據(jù)監(jiān)視和子節(jié)點監(jiān)視(data watches and child watches) getData() and exists() 設(shè)置數(shù)據(jù)監(jiān)視鞍历,getChildren() 設(shè)置子節(jié)點監(jiān)視。 或者肪虎,你也可以想象 Zookeeper 設(shè)置的不同監(jiān)視返回不同的數(shù)據(jù)劣砍,getData() 和 exists() 返回 znode 節(jié)點的相關(guān)信息,而 getChildren() 返回子節(jié)點列表扇救。因此刑枝, setData() 會觸發(fā)設(shè)置在某一節(jié)點上所設(shè)置的數(shù)據(jù)監(jiān)視(假定數(shù)據(jù)設(shè)置成功),而一次成功的 create() 操作則會出發(fā)當(dāng)前節(jié)點上所設(shè)置的數(shù)據(jù)監(jiān)視以及父節(jié)點的子節(jié)點監(jiān)視迅腔。一次成功的 delete() 操作將會觸發(fā)當(dāng)前節(jié)點的數(shù)據(jù)監(jiān)視和子節(jié)點監(jiān)視事件装畅,同時也會觸發(fā)該節(jié)點父節(jié)點的child watch

Zookeeper 中的監(jiān)視是輕量級的沧烈,因此容易設(shè)置掠兄、維護和分發(fā)。當(dāng)客戶端與 Zookeeper 服務(wù)器端失去聯(lián)系時锌雀,客戶端并不會收到監(jiān)視事件的通知蚂夕,只有當(dāng)客戶端重新連接后,若在必要的情況下腋逆,以前注冊的監(jiān)視會重新被注冊并觸發(fā)婿牍,對于開發(fā)人員來說 這通常是透明的。只有一種情況會導(dǎo)致監(jiān)視事件的丟失惩歉,即:通過 exists() 設(shè)置了某個 znode 節(jié)點的監(jiān)視等脂,但是如果某個客戶端在此 znode 節(jié)點被創(chuàng)建和刪除的時間間隔內(nèi)與 zookeeper 服務(wù)器失去了聯(lián)系,該客戶端即使稍后重新連接 zookeeper服務(wù)器后也得不到事件通知撑蚌。

4.4 ACL訪問控制列表##

這是另外一個和Linux操作系統(tǒng)非常相似的地方上遥,ZooKeeper使用ACL來控制對旗下Znode結(jié)點們的訪問。ACL的實現(xiàn)和Linux文件系統(tǒng)的訪問權(quán)限十分類似:它通過設(shè)置權(quán)限為來表明是否允許對一個結(jié)點的相關(guān)內(nèi)容的改變争涌。

但是與傳統(tǒng)Linux機制不太相同露该,一個結(jié)點的數(shù)據(jù)沒有類似“擁有者,組用戶第煮,其他用戶”的概念解幼,在ZooKeeper中,ACL通過設(shè)置ID以及與其關(guān)聯(lián)的權(quán)限來完成訪問控制的包警。ACL的權(quán)限組成語法是:

(scheme:expression, perms)

前者表明設(shè)置的ID撵摆,逗號后面表示的是ID相關(guān)的權(quán)限,例如:

(ip:172.16.16.1,READ)

指明了IP地址為如上的用戶的權(quán)限為只讀害晦。

以下列舉以下ACL所具有的權(quán)限:

CREATE:表明你可以創(chuàng)建一個Znode的子結(jié)點特铝。
READ:你可以得到這個結(jié)點的數(shù)據(jù)以及列舉該結(jié)點的子結(jié)點情況。
WRITE:設(shè)置一個結(jié)點的數(shù)據(jù)壹瘟。
DELETE:可以刪除一個結(jié)點
ADMIN:對一個結(jié)點設(shè)置權(quán)限鲫剿。

5 Zookeeper部署#

ZooKeeper的部署方式主要有三種,單機模式稻轨、偽集群模式灵莲、集群模式。其實剩下的兩種模式都是集群模式的特殊情況殴俱。

5.1 系統(tǒng)環(huán)境##

系統(tǒng)環(huán)境

5.2 下載Zookeeper##

  1. mkdir /home/taomk/zk 創(chuàng)建文件夾

  2. cd /home/taomk/zk; wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz 下載

  3. tar xvf zookeeper-3.4.6.tar.gz 解壓縮

  4. mv zookeeper-3.4.6 zookeeper346 重命名

  5. cd zookeeper346; ls -l

image.png

5.3 配置環(huán)境變量##

export ZOOKEEPER_HOME=/home/taomk/zk/zookeeper346
export PATH=$PATH:$ZOOKEEPER_HOME/bin:$ZOOKEEPER_HOME/conf

5.4 ZooKeeper的單機模式部署##

ZooKeeper的單機模式通常是用來快速測試客戶端應(yīng)用程序的政冻,在實際過程中不可能是單機模式。單機模式的配置也比較簡單线欲。

  1. 編寫配置文件zoo.cfg:ZooKeeper的運行默認是讀取zoo.cfg文件里面的內(nèi)容的明场。
~mkdir /home/taomk/zk/zoo/zk0
~cp conf/zoo_sample.cfg conf/zk0.cfg
~vim conf/zk0.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/conan/zoo/zk0
clientPort=2181

在zk0.cfg這個文件中,我們需要指定 dataDir 的值李丰,它指向了一個目錄古拴,這個目錄在開始的時候需要為空。下面是每個參數(shù)的含義:

tickTime :基本事件單元辅柴,以毫秒為單位誉察。這個時間是作為 Zookeeper 服務(wù)器之間或客戶端與服務(wù)器之間維持心跳的時間間隔,也就是每個 tickTime 時間就會發(fā)送一個心跳踱讨。

dataDir :存儲內(nèi)存中數(shù)據(jù)庫快照的位置魏蔗,顧名思義就是 Zookeeper 保存數(shù)據(jù)的目錄,默認情況下痹筛,Zookeeper 將寫數(shù)據(jù)的日志文件也保存在這個目錄里莺治。

clientPort :這個端口就是客戶端連接 Zookeeper 服務(wù)器的端口,Zookeeper 會監(jiān)聽這個端口帚稠,接受客戶端的訪問請求谣旁。

使用單機模式時用戶需要注意:這種配置方式下沒有 ZooKeeper 副本,所以如果 ZooKeeper 服務(wù)器出現(xiàn)故障滋早, ZooKeeper 服務(wù)將會停止榄审。

  1. 啟動Zookeeper
~bin/zkServer.sh start zk0.cfg
image.png

zk的服務(wù)顯示為QuorumPeerMain

~jps
5321 QuorumPeerMain
5338 Jps

查看運行狀態(tài)

~bin/zkServer.sh status zk0.cfg
JMX enabled by default
Using config: /home/taomk/zk/zookeeper346/bin/../conf/zk0.cfg
Mode: standalone

單節(jié)點的時,Mode會顯示為standalone杆麸。

  1. 停止ZooKeeper服務(wù)
~ bin/zkServer.sh stop zk0.cfg
JMX enabled by default
Using config: /home/taomk/zk/zookeeper346/bin/../conf/zk0.cfg
Stopping zookeeper ... STOPPED

5.5 ZooKeeper的偽集群模式部署##

所謂 “偽分布式集群” 就是在搁进,在一臺PC中浪感,啟動多個ZooKeeper的實例”剩“完全分布式集群” 是每臺PC影兽,啟動一個ZooKeeper實例。其實在企業(yè)中式不會存在的莱革,另外為了測試一個客戶端程序也沒有必要存在峻堰,只有在物質(zhì)條件比較匱乏的條件下才會存在的模式。集群偽分布模式就是在單機下模擬集群的ZooKeeper服務(wù)盅视,在一臺機器上面有多個ZooKeeper的JVM同時運行捐名。

ZooKeeper的集群模式下,多個Zookeeper服務(wù)器在工作前會選舉出一個Leader闹击,在接下來的工作中這個被選舉出來的Leader死了镶蹋,而剩下的Zookeeper服務(wù)器會知道這個Leader死掉了,在活著的Zookeeper集群中會繼續(xù)選出一個Leader拇砰,選舉出Leader的目的是為了可以在分布式的環(huán)境中保證數(shù)據(jù)的一致性梅忌。

  1. 確認集群服務(wù)器的數(shù)量

由于ZooKeeper集群中,會有一個Leader負責(zé)管理和協(xié)調(diào)其他集群服務(wù)器除破,因此服務(wù)器的數(shù)量通常都是單數(shù)牧氮,例如3,5瑰枫,7...等踱葛,這樣2n+1的數(shù)量的服務(wù)器就可以允許最多n臺服務(wù)器的失效

  1. 創(chuàng)建環(huán)境目錄
~ mkdir /home/taomk/zk/zoo/zk1
~ mkdir /home/taomk/zk/zoo/zk2
~ mkdir /home/taomk/zk/zoo/zk3

#新建myid文件
~ echo "1" > /home/taomk/zk/zoo/zk1/myid
~ echo "2" > /home/taomk/zk/zoo/zk2/myid
~ echo "3" > /home/taomk/zk/zoo/zk3/myid
  1. 分別修改配置文件

修改:dataDir,clientPort

增加:集群的實例光坝,server.X尸诽,”X”表示每個目錄中的myid的值

~ vim /home/taomk/zk/zookeeper346/conf/zk1.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/taomk/zk/zoo/zk1
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

~ vim /home/taomk/zk/zookeeper346/conf/zk2.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/taomk/zk/zoo/zk2
clientPort=2182
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890

~ vim /home/taomk/zk/zookeeper346/conf/zk3.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/taomk/zk/zoo/zk3
clientPort=2183
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890

initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這里所說的客戶端不是用戶連接 Zookeeper 服務(wù)器的客戶端,而是 Zookeeper 服務(wù)器集群中連接到 Leader 的 Follower 服務(wù)器初始化連接時最長能忍受多少個心跳時間間隔數(shù)盯另。當(dāng)已經(jīng)超過 10 個心跳的時間(也就是 tickTime)長度后 Zookeeper 服務(wù)器還沒有收到客戶端的返回信息性含,那么表明這個客戶端連接失敗≡Ч撸總的時間長度就是 10*2000=20 秒商蕴。

syncLimit:這個配置項標(biāo)識 Leader 與 Follower 之間發(fā)送消息,請求和應(yīng)答時間長度芝发,最長不能超過多少個 tickTime 的時間長度绪商,總的時間長度就是 5*2000=10 秒。

server.A=B:C:D:其中 A 是一個數(shù)字辅鲸,表示這個是第幾號服務(wù)器格郁,就是集群模式下配置的myid文件所存放的數(shù)值;B 是這個服務(wù)器的 ip 地址;C 表示的是這個服務(wù)器與集群中的 Leader 服務(wù)器交換信息的端口例书;D 表示的是萬一集群中的 Leader 服務(wù)器掛了锣尉,需要一個端口來重新進行選舉,選出一個新的 Leader雾叭,而這個端口就是用來執(zhí)行選舉時服務(wù)器相互通信的端口悟耘。如果是偽集群的配置方式,由于 B 都是一樣织狐,所以不同的 Zookeeper 實例通信端口號不能一樣,所以要給它們分配不同的端口號筏勒。

由于三個服務(wù)都在同一臺電腦上移迫,因此這里要保證地址的唯一性,因此要特別注意IP地址和端口號不要互相沖突管行,以免影響程序的正確執(zhí)行厨埋。

3個節(jié)點的ZooKeeper集群配置完成,接下來我們的啟動服務(wù)捐顷。

  1. 啟動集群
~ bin/zkServer.sh start zk1.cfg
~ bin/zkServer.sh start zk2.cfg
~ bin/zkServer.sh start zk3.cfg

~ jps
5422 QuorumPeerMain
5395 QuorumPeerMain
5463 QuorumPeerMain
5494 Jps

#查看節(jié)點狀態(tài)
~ bin/zkServer.sh status zk1.cfg
JMX enabled by default
Using config: /home/taomk/zk/zookeeper346/bin/../conf/zk1.cfg
Mode: follower

~ bin/zkServer.sh status zk2.cfg
JMX enabled by default
Using config: /home/taomk/zk/zookeeper346/bin/../conf/zk2.cfg
Mode: leader

~ bin/zkServer.sh status zk3.cfg
JMX enabled by default
Using config: /home/taomk/zk/zookeeper346/bin/../conf/zk3.cfg
Mode: follower
  1. 查看ZooKeeper物理文件目錄結(jié)構(gòu)
~ tree -L 3 /home/taomk/zk/zoo
image.png

5.6 ZooKeeper Distributed模式##

ZooKeeper分布式模式安裝(ZooKeeper集群)也比較容易荡陷,這里說明一下基本要點。

首先要明確的是迅涮,ZooKeeper集群是一個獨立的分布式協(xié)調(diào)服務(wù)集群废赞,“獨立”的含義就是說,如果想使用ZooKeeper實現(xiàn)分布式應(yīng)用的協(xié)調(diào)與管理叮姑,簡化協(xié)調(diào)與管理唉地,任何分布式應(yīng)用都可以使用,這就要歸功于Zookeeper的數(shù)據(jù)模型(Data Model)和層次命名空間(Hierarchical Namespace)結(jié)構(gòu)传透,在設(shè)計你的分布式應(yīng)用協(xié)調(diào)服務(wù)時耘沼,首要的就是考慮如何組織層次命名空間。

下面說明分布式模式的安裝配置朱盐,過程如下所示:

  1. 第一步:主機名稱到IP地址映射配置

ZooKeeper集群中具有兩個關(guān)鍵的角色:Leader和Follower群嗤。集群中所有的結(jié)點作為一個整體對分布式應(yīng)用提供服務(wù),集群中每個結(jié)點之間都互相連接兵琳,所以狂秘,在配置的ZooKeeper集群的時候,每一個結(jié)點的host到IP地址的映射都要配置上集群中其它結(jié)點的映射信息闰围。

例如赃绊,ZooKeeper集群中每個結(jié)點的配置,以slave-01為例羡榴,/etc/hosts內(nèi)容如下所示:

192.168.0.179   slave-01  
192.168.0.178   slave-02  
192.168.0.177   slave-03

ZooKeeper采用一種稱為Leader election的選舉算法碧查。在整個集群運行過程中,只有一個Leader,其他的都是Follower忠售,如果ZooKeeper集群在運行過程中Leader出了問題传惠,系統(tǒng)會采用該算法重新選出一個Leader。因此稻扬,各個結(jié)點之間要能夠保證互相連接卦方,必須配置上述映射。

ZooKeeper集群啟動的時候泰佳,會首先選出一個Leader盼砍,在Leader election過程中,某一個滿足選舉算法的結(jié)點就能成為Leader逝她。

  1. 第二步:修改ZooKeeper配置文件

在其中一臺機器(slave-01)上浇坐,解壓縮zookeeper-3.3.4.tar.gz,修改配置文件conf/zoo.cfg黔宛,內(nèi)容如下所示:

tickTime=2000  
dataDir=/home/hadoop/storage/zookeeper  
clientPort=2181  
initLimit=5  
syncLimit=2  
server.1=slave-01:2888:3888  
server.2=slave-02:2888:3888  
server.3=slave-03:2888:3888 
  1. 第三步:遠程復(fù)制分發(fā)安裝文件

上面已經(jīng)在一臺機器slave-01上配置完成ZooKeeper近刘,現(xiàn)在可以將該配置好的安裝文件遠程拷貝到集群中的各個結(jié)點對應(yīng)的目錄下:

cd /home/hadoop/installation/  
scp -r zookeeper-3.3.4/ hadoop@slave-02:/home/hadoop/installation/  
scp -r zookeeper-3.3.4/ hadoop@slave-03:/home/hadoop/installation/
  1. 第四步:設(shè)置myid

在我們配置的dataDir指定的目錄下面,創(chuàng)建一個myid文件臀晃,里面內(nèi)容為一個數(shù)字觉渴,用來標(biāo)識當(dāng)前主機,conf/zoo.cfg文件中配置的server.X中X為什么數(shù)字徽惋,則myid文件中就輸入這個數(shù)字案淋,例如:

hadoop@slave-01:~/installation/zookeeper-3.3.4$ echo "1" > /home/hadoop/storage/zookeeper/myid  
hadoop@slave-02:~/installation/zookeeper-3.3.4$ echo "2" > /home/hadoop/storage/zookeeper/myid  
hadoop@slave-03:~/installation/zookeeper-3.3.4$ echo "3" > /home/hadoop/storage/zookeeper/myid 
  1. 第五步:啟動ZooKeeper集群

在ZooKeeper集群的每個結(jié)點上,執(zhí)行啟動ZooKeeper服務(wù)的腳本寂曹,如下所示:

hadoop@slave-01:~/installation/zookeeper-3.3.4$ bin/zkServer.sh start  
hadoop@slave-02:~/installation/zookeeper-3.3.4$ bin/zkServer.sh start  
hadoop@slave-03:~/installation/zookeeper-3.3.4$ bin/zkServer.sh start

啟動的順序是slave-01>slave-02>slave-03哎迄,由于ZooKeeper集群啟動的時候,每個結(jié)點都試圖去連接集群中的其它結(jié)點隆圆,先啟動的肯定連不上后面還沒啟動的漱挚,所以日志前面部分的異常是可以忽略的。通過后面部分可以看到渺氧,集群在選出一個Leader后旨涝,最后穩(wěn)定了。其他結(jié)點可能也出現(xiàn)類似問題侣背,屬于正常白华。

6 Zookeeper命令行操作#

ZooKeeper命令行工具類似于Linux的shell環(huán)境,不過功能肯定不及shell啦贩耐,但是使用它我們可以簡單的對ZooKeeper進行訪問弧腥,數(shù)據(jù)創(chuàng)建,數(shù)據(jù)修改等操作潮太。

對于客戶端來說管搪,ZooKeeper是一個整體(ensemble)虾攻,連接到ZooKeeper集群實際上感覺在獨享整個集群的服務(wù),所以更鲁,你可以在任何一個結(jié)點上建立到服務(wù)集群的連接霎箍。

當(dāng)啟動 ZooKeeper 服務(wù)成功之后,輸入下述命令澡为,連接到 ZooKeeper 服務(wù):

~ bin/zkCli.sh –server 127.0.0.1:2181

連接成功后漂坏,系統(tǒng)會輸出 ZooKeeper 的相關(guān)環(huán)境以及配置信息,并在屏幕輸出“ Welcome to ZooKeeper ”等信息媒至。

命令行工具的一些簡單操作如下:

  1. 使用 ls 命令來查看當(dāng)前 ZooKeeper 中所包含的內(nèi)容
ls /
image.png
  1. 創(chuàng)建一個新的 znode 顶别,使用 create /zk myData 。這個命令創(chuàng)建了一個新的 znode 節(jié)點“ zk ”以及與它關(guān)聯(lián)的字符串:
create /zk "myData"
image.png
  1. 運行 get 命令來確認 znode 是否包含我們所創(chuàng)建的字符串:
get /zk
image.png
  1. 通過 set 命令來對 zk 所關(guān)聯(lián)的字符串進行設(shè)置
set /zk "zsl"
get /zk
image.png
  1. znode 刪除
delete /zk
  1. 通過help打印命令行幫助
image.png
  1. 退出客戶端連接
quit

7 Java編程現(xiàn)實命令行操作#

  1. ZkDemo.java
public class ZkDemo {

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        // 創(chuàng)建一個與服務(wù)器的連接
        ZooKeeper zk = new ZooKeeper("127.0.0.1:2181", 60000, new Watcher() {
            // 監(jiān)控所有被觸發(fā)的事件
            public void process(WatchedEvent event) {
                System.out.println("EVENT:" + event.getType());
            }
        });

        // 查看根節(jié)點
        System.out.println("ls / => " + zk.getChildren("/", true));

        // 創(chuàng)建一個目錄節(jié)點
        if (zk.exists("/node", true) == null) {
            zk.create("/node", "conan".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("create /node conan");
            // 查看/node節(jié)點數(shù)據(jù)
            System.out.println("get /node => " + new String(zk.getData("/node", false, null)));
            // 查看根節(jié)點
            System.out.println("ls / => " + zk.getChildren("/", true));
        }

        // 創(chuàng)建一個子目錄節(jié)點
        if (zk.exists("/node/sub1", true) == null) {
            zk.create("/node/sub1", "sub1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("create /node/sub1 sub1");
            // 查看node節(jié)點
            System.out.println("ls /node => " + zk.getChildren("/node", true));
        }

        // 修改節(jié)點數(shù)據(jù)
        if (zk.exists("/node", true) != null) {
            zk.setData("/node", "changed".getBytes(), -1);
            // 查看/node節(jié)點數(shù)據(jù)
            System.out.println("get /node => " + new String(zk.getData("/node", false, null)));
        }

        // 刪除節(jié)點
        if (zk.exists("/node/sub1", true) != null) {
            zk.delete("/node/sub1", -1);
            zk.delete("/node", -1);
            // 查看根節(jié)點
            System.out.println("ls / => " + zk.getChildren("/", true));
        }

        // 關(guān)閉連接
        zk.close();
    }
}
  1. pom.xml塘慕,maven配置文件
<dependencies>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.6</version>
        <exclusions>
            <exclusion>
                <groupId>javax.jms</groupId>
                <artifactId>jms</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.sun.jdmk</groupId>
                <artifactId>jmxtools</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.sun.jmx</groupId>
                <artifactId>jmxri</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末筋夏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子图呢,更是在濱河造成了極大的恐慌,老刑警劉巖骗随,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛤织,死亡現(xiàn)場離奇詭異,居然都是意外死亡鸿染,警方通過查閱死者的電腦和手機指蚜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涨椒,“玉大人摊鸡,你說我怎么就攤上這事〔隙” “怎么了免猾?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長囤热。 經(jīng)常有香客問我猎提,道長,這世上最難降的妖魔是什么旁蔼? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任锨苏,我火速辦了婚禮,結(jié)果婚禮上棺聊,老公的妹妹穿的比我還像新娘伞租。我一直安慰自己,他們只是感情好限佩,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布葵诈。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪驯击。 梳的紋絲不亂的頭發(fā)上烁兰,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音徊都,去河邊找鬼沪斟。 笑死,一個胖子當(dāng)著我的面吹牛暇矫,可吹牛的內(nèi)容都是我干的主之。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼李根,長吁一口氣:“原來是場噩夢啊……” “哼槽奕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起房轿,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤粤攒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后囱持,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夯接,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年纷妆,在試婚紗的時候發(fā)現(xiàn)自己被綠了盔几。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡掩幢,死狀恐怖逊拍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情际邻,我是刑警寧澤芯丧,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站枯怖,受9級特大地震影響注整,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜度硝,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一肿轨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蕊程,春花似錦椒袍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玫恳。三九已至,卻和暖如春优俘,著一層夾襖步出監(jiān)牢的瞬間京办,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工帆焕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惭婿,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓叶雹,卻偏偏與公主長得像财饥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子折晦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容