ZooKeeper由雅虎研究院開發(fā),是Google Chubby的開源實(shí)現(xiàn),后來(lái)托管到Apache,于2010年11月正式成為Apache的頂級(jí)項(xiàng)目。
ZooKeeper是一個(gè)經(jīng)典的分布式數(shù)據(jù)一致性解決方案,致力于為分布式應(yīng)用提供一個(gè)高性能、高可用,且具有嚴(yán)格順序訪問控制能力的分布式協(xié)調(diào)服務(wù)。
分布式應(yīng)用程序可以基于ZooKeeper實(shí)現(xiàn)數(shù)據(jù)發(fā)布與訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)與通知、集群管理、Leader選舉、分布式鎖、分布式隊(duì)列等功能。
ZooKeeper致力于為分布式應(yīng)用提供一個(gè)高性能、高可用,且具有嚴(yán)格順序訪問控制能力的分布式協(xié)調(diào)服務(wù)
ZooKeeper將全量數(shù)據(jù)存儲(chǔ)在內(nèi)存中,并直接服務(wù)于客戶端的所有非事務(wù)請(qǐng)求,尤其適用于以讀為主的應(yīng)用場(chǎng)景
ZooKeeper一般以集群的方式對(duì)外提供服務(wù),一般3 ~ 5臺(tái)機(jī)器就可以組成一個(gè)可用的Zookeeper集群了,每臺(tái)機(jī)器都會(huì)在內(nèi)存中維護(hù)當(dāng)前的服務(wù)器狀態(tài),并且每臺(tái)機(jī)器之間都相互保持著通信。只要集群中超過一般的機(jī)器都能夠正常工作,那么整個(gè)集群就能夠正常對(duì)外服務(wù)
對(duì)于來(lái)自客戶端的每個(gè)更新請(qǐng)求,ZooKeeper都會(huì)分配一個(gè)全局唯一的遞增編號(hào),這個(gè)編號(hào)反映了所有事務(wù)操作的先后順序
ZooKeeper一般以集群的方式對(duì)外提供服務(wù),一個(gè)集群包含多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)對(duì)應(yīng)一臺(tái)ZooKeeper服務(wù)器,所有的節(jié)點(diǎn)共同對(duì)外提供服務(wù),整個(gè)集群環(huán)境對(duì)分布式數(shù)據(jù)一致性提供了全面的支持,具體包括以下五大特性:
從同一個(gè)客戶端發(fā)起的請(qǐng)求,最終將會(huì)嚴(yán)格按照其發(fā)送順序進(jìn)入ZooKeeper中
所有請(qǐng)求的響應(yīng)結(jié)果在整個(gè)分布式集群環(huán)境中具備原子性,即要么整個(gè)集群中所有機(jī)器都成功的處理了某個(gè)請(qǐng)求,要么就都沒有處理,絕對(duì)不會(huì)出現(xiàn)集群中一部分機(jī)器處理了某一個(gè)請(qǐng)求,而另一部分機(jī)器卻沒有處理的情況
無(wú)論客戶端連接到ZooKeeper集群中哪個(gè)服務(wù)器,每個(gè)客戶端所看到的服務(wù)端模型都是一致的,不可能出現(xiàn)兩種不同的數(shù)據(jù)狀態(tài),因?yàn)閆ooKeeper集群中每臺(tái)服務(wù)器之間會(huì)進(jìn)行數(shù)據(jù)同步
一旦服務(wù)端數(shù)據(jù)的狀態(tài)發(fā)送了變化,就會(huì)立即存儲(chǔ)起來(lái),除非此時(shí)有另一個(gè)請(qǐng)求對(duì)其進(jìn)行了變更,否則數(shù)據(jù)一定是可靠的
當(dāng)某個(gè)請(qǐng)求被成功處理后,ZooKeeper僅僅保證在一定的時(shí)間段內(nèi),客戶端最終一定能從服務(wù)端上讀取到最新的數(shù)據(jù)狀態(tài),即ZooKeeper保證數(shù)據(jù)的最終一致性
在分布式系統(tǒng)中,集群中每臺(tái)機(jī)器都有自己的角色,ZooKeeper沒有沿用傳統(tǒng)的Master/Slave模式(主備模式),而是引入了Leader、Follower和Observer三種角色
集群通過一個(gè)Leader選舉過程從所有的機(jī)器中選舉一臺(tái)機(jī)器作為”Leader”,Leader能為客戶端提供讀和寫服務(wù)
Leader服務(wù)器是整個(gè)集群工作機(jī)制的核心,主要工作:
事務(wù)請(qǐng)求的唯一調(diào)度者和處理者,保證集群事務(wù)處理的順序性
集群內(nèi)部各服務(wù)器的調(diào)度者
顧名思義,F(xiàn)ollower是追隨者,主要工作:
參與Leader選舉投票
處理客戶端非事務(wù)請(qǐng)求 - 即讀服務(wù)
轉(zhuǎn)發(fā)事務(wù)請(qǐng)求給Leader服務(wù)器
參與事務(wù)請(qǐng)求Proposal的投票
Observer是ZooKeeper自3.3.0版本開始引入的一個(gè)全新的服務(wù)器角色,充當(dāng)一個(gè)觀察者角色,工作原理和Follower基本是一致的,和Follower唯一的區(qū)別是Observer不參與任何形式的投票
處理客戶端非事務(wù)請(qǐng)求 - 即讀服務(wù)
轉(zhuǎn)發(fā)事務(wù)請(qǐng)求給Leader服務(wù)器
不參與Leader選舉投票
參與事務(wù)請(qǐng)求Proposal的投票
所以O(shè)bserver可以在不影響寫性能的情況下提升集群的讀性能
ZooKeeper并非采用經(jīng)典的分布式一致性協(xié)議 - Paxos,而是參考了Paxos設(shè)計(jì)了一種更加輕量級(jí)的支持崩潰可恢復(fù)的原子廣播協(xié)議-Zab(ZooKeeper Atomic Broadcast)。
ZAB協(xié)議分為兩個(gè)階段 - Leader Election(領(lǐng)導(dǎo)選舉)和Atomic Broadcast(原子廣播)
當(dāng)集群?jiǎn)?dòng)時(shí),會(huì)選舉一臺(tái)節(jié)點(diǎn)為L(zhǎng)eader,而其他節(jié)點(diǎn)為Follower,當(dāng)Leader節(jié)點(diǎn)出現(xiàn)網(wǎng)絡(luò)中斷、崩潰退出與重啟等異常情況,ZAB會(huì)進(jìn)入恢復(fù)模式并選舉產(chǎn)生新的Leader服務(wù)器,當(dāng)集群中已有過半機(jī)器與該Leader服務(wù)器完成數(shù)據(jù)狀態(tài)同步,退出恢復(fù)模式
當(dāng)領(lǐng)導(dǎo)選舉完成后,就進(jìn)入原子廣播階段。此時(shí)集群中已存在一個(gè)Leader服務(wù)器在進(jìn)行消息廣播,當(dāng)一臺(tái)同樣遵循ZAB協(xié)議的服務(wù)器啟動(dòng)后加入到集群中,新加的服務(wù)器會(huì)自動(dòng)進(jìn)入數(shù)據(jù)恢復(fù)階段
在ZooKeeper中,事務(wù)是指能夠改變ZooKeeper服務(wù)器狀態(tài)的請(qǐng)求,一般指創(chuàng)建節(jié)點(diǎn)、更新數(shù)據(jù)、刪除節(jié)點(diǎn)以及創(chuàng)建會(huì)話操作
為了保證事務(wù)請(qǐng)求被順序執(zhí)行,從而確保ZooKeeper集群的數(shù)據(jù)一致性,所有的事務(wù)請(qǐng)求必須由Leader服務(wù)器處理,ZooKeeper實(shí)現(xiàn)了非常特別的事務(wù)請(qǐng)求轉(zhuǎn)發(fā)機(jī)制:
所有非Leader服務(wù)器如果接收到來(lái)自客戶端的事務(wù)請(qǐng)求,必須將其轉(zhuǎn)發(fā)給Leader服務(wù)器來(lái)處理
在分布式系統(tǒng)中,事務(wù)請(qǐng)求可能存在依賴關(guān)系,如變更C需要依賴變更A和變更B,這樣就要求ZAB協(xié)議能夠保證如果一個(gè)狀態(tài)變更成功被處理了,那么其所有依賴的狀態(tài)變更都應(yīng)該已經(jīng)提前被處理掉了。
在ZooKeeper中對(duì)每一個(gè)事務(wù)請(qǐng)求,都會(huì)為其分配一個(gè)全局唯一的事務(wù)ID,使用ZXID表示,通常是一個(gè)64位的數(shù)字。每一個(gè)ZXID對(duì)應(yīng)一次事務(wù),從這些ZXID可以間接識(shí)別出ZooKeeper處理這些事務(wù)請(qǐng)求的全局順序
ZooKeeper內(nèi)部擁有一個(gè)樹狀的內(nèi)存模型,類似文件系統(tǒng),只是在ZooKeeper中將這些目錄與文件系統(tǒng)統(tǒng)稱為ZNode,ZNode是ZooKeeper中數(shù)據(jù)的最小單元,每個(gè)ZNode上可以保存數(shù)據(jù),還可以掛載子節(jié)點(diǎn),因此構(gòu)成了一個(gè)層次化的命名空間
ZooKeeper中使用斜杠(/)分割的路徑表示ZNode路徑,斜杠(/)表示根節(jié)點(diǎn)
在ZooKeeper中,每個(gè)數(shù)據(jù)節(jié)點(diǎn)ZNode都是有生命周期的,其生命周期的長(zhǎng)短取決于ZNode的節(jié)點(diǎn)類型
為了有效保障ZooKeeper中數(shù)據(jù)的安全,避免因誤操作而帶來(lái)數(shù)據(jù)隨意變更導(dǎo)致分布式系統(tǒng)異常,ZooKeeper提供了一套完善的ACL(Access Contro List)權(quán)限控制機(jī)制來(lái)保障數(shù)據(jù)的安全。
可以從三個(gè)方面理解ACL機(jī)制,分別是:權(quán)限模式(Scheme)、授權(quán)對(duì)象(ID)和權(quán)限(Permission),通常使用”scheme:id:permission”來(lái)標(biāo)識(shí)一個(gè)有效的ACL信息
每個(gè)數(shù)據(jù)節(jié)點(diǎn)ZNode除了存儲(chǔ)數(shù)據(jù)內(nèi)容外,還存儲(chǔ)了數(shù)據(jù)節(jié)點(diǎn)本身的一些狀態(tài)信息
ZooKeeper為數(shù)據(jù)節(jié)點(diǎn)引入版本的概念,對(duì)個(gè)數(shù)據(jù)節(jié)點(diǎn)都具有三種類型的版本信息,對(duì)數(shù)據(jù)節(jié)點(diǎn)的任何更新操作都會(huì)引起版本號(hào)的變化
在分布式系統(tǒng)中,在運(yùn)行過程中往往需要保證數(shù)據(jù)訪問的排他性。Java并發(fā)中是實(shí)現(xiàn)了對(duì)CAS的指令支持,即對(duì)于值V,每次更新前都會(huì)比對(duì)其值是否是預(yù)期值A(chǔ),只有符合預(yù)期,才會(huì)將V原子化的更新到新值B
而ZooKeeper每個(gè)節(jié)點(diǎn)都有數(shù)據(jù)版本的概念,在調(diào)用更新操作的時(shí)候,先從請(qǐng)求中獲取當(dāng)前請(qǐng)求的版本version,同時(shí)獲取服務(wù)器上該數(shù)據(jù)最新版本currentVersion,如果無(wú)法匹配,就無(wú)法更新成功,這樣可以有效避免一些分布式更新的并發(fā)問題
在ZooKeeper中,引入Watcher機(jī)制來(lái)實(shí)現(xiàn)分布式數(shù)據(jù)的發(fā)布/訂閱功能。ZooKeeper允許客戶端向服務(wù)器注冊(cè)一個(gè)Watcher監(jiān)聽,當(dāng)服務(wù)器的一些指定事件觸發(fā)了這個(gè)Watcher,那么就會(huì)向指定客戶端發(fā)送一個(gè)事件通知來(lái)實(shí)現(xiàn)分布式的通知功能
Watcher機(jī)制為以下三個(gè)過程:
在創(chuàng)建一個(gè)ZooKeeper客戶端對(duì)象實(shí)例時(shí),可以向構(gòu)造方法中傳入一個(gè)Watcher,這個(gè)Watcher將作為整個(gè)ZooKeeper會(huì)話期間的默認(rèn)Watcher,一致保存在客戶端,并向ZooKeeper服務(wù)器注冊(cè)Watcher
客戶端并不會(huì)把真實(shí)的Watcher對(duì)象傳遞到服務(wù)器,僅僅只是在客戶端請(qǐng)求中使用boolean類型屬性進(jìn)行標(biāo)記,降低網(wǎng)絡(luò)開銷和服務(wù)器內(nèi)存開銷
服務(wù)端執(zhí)行數(shù)據(jù)變更,當(dāng)Watcher監(jiān)聽的對(duì)應(yīng)數(shù)據(jù)節(jié)點(diǎn)的數(shù)據(jù)內(nèi)容發(fā)生變更,如果找到對(duì)應(yīng)的Watcher,會(huì)將其提取出來(lái),同時(shí)從管理中將其刪除(說明Watcher在服務(wù)端是一次性的,即觸發(fā)一次就失效了),觸發(fā)Watcher,向客戶端發(fā)送通知
客戶端獲取通知,識(shí)別出事件類型,從相應(yīng)的Watcher存儲(chǔ)中去除對(duì)應(yīng)的Watcher(說明客戶端也是一次性的,即一旦觸發(fā)就會(huì)失效)
一致性:無(wú)論是客戶端還是服務(wù)器,一旦一個(gè)Watcher被處罰,ZooKeeper都會(huì)將其從相應(yīng)的存儲(chǔ)中移除,因此開發(fā)人員在Watcher使用上要反復(fù)注冊(cè),這樣可以有效減輕服務(wù)器壓力
客戶端串行執(zhí)行:客戶端Watcher回調(diào)的過程是一個(gè)串行同步的過程,這保證了順序
輕量:客戶端并不會(huì)把真實(shí)的Watcher對(duì)象傳遞到服務(wù)器,僅僅只是在客戶端請(qǐng)求中使用boolean類型屬性進(jìn)行標(biāo)記,降低網(wǎng)絡(luò)開銷和服務(wù)器內(nèi)存開銷
Session是指客戶端連接 - 客戶端和服務(wù)器之間的一個(gè)TCP長(zhǎng)連接
會(huì)話在整個(gè)生命周期中,會(huì)在不同的會(huì)話轉(zhuǎn)態(tài)之間進(jìn)行切換
Session是ZooKeeper中的會(huì)話實(shí)體,代表了一個(gè)客戶端會(huì)話,其包含4個(gè)屬性:
為了保證客戶端會(huì)話的有效性,客戶端會(huì)在會(huì)話超時(shí)時(shí)間范圍內(nèi)向服務(wù)器發(fā)送PING請(qǐng)求來(lái)保持會(huì)話的有效性,即心跳檢測(cè)。
服務(wù)器接收到客戶端的這個(gè)心跳檢測(cè),就會(huì)重新激活對(duì)應(yīng)的客戶端會(huì)話
服務(wù)器的超級(jí)檢查線程會(huì)在指定時(shí)間點(diǎn)進(jìn)行檢查,整理出一些已經(jīng)過期的會(huì)話后,就要開始進(jìn)行會(huì)話清理了:
關(guān)閉會(huì)話
清理相關(guān)的臨時(shí)節(jié)點(diǎn)
當(dāng)客戶端和服務(wù)器之間網(wǎng)絡(luò)連接斷開,客戶端會(huì)自動(dòng)進(jìn)行反復(fù)的重連,直到最終成功連接上ZooKeeper集群中的一臺(tái)機(jī)器
在會(huì)話超時(shí)時(shí)間內(nèi)重新連接上,被視為重連成功
在會(huì)話超時(shí)時(shí)間外重新連接上,此時(shí)服務(wù)器已經(jīng)進(jìn)行了會(huì)話清理,但客戶端不知道會(huì)話已經(jīng)失效,重新連接服務(wù)器會(huì)告訴客戶端會(huì)話已失效,被視為非法會(huì)話
在此階段,我們已經(jīng)充分了解了什么是Zookeeper了,那么我們接下來(lái)用它能做什么,單機(jī)模式的安裝,以及它的使用來(lái)為大家做詳細(xì)介紹。
zookeeper功能非常強(qiáng)大,可以實(shí)現(xiàn)諸如分布式應(yīng)用配置管理、統(tǒng)一命名服務(wù)、狀態(tài)同步服務(wù)、集群管理等功能,我們這里拿比較簡(jiǎn)單的分布式應(yīng)用配置管理為例來(lái)說明。
假設(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)聽,一旦配置信息發(fā)生變化,每個(gè)應(yīng)用程序就會(huì)收到 zookeeper 的通知,然后從 zookeeper 獲取新的配置信息應(yīng)用到系統(tǒng)中。
如上,你大致應(yīng)該了解zookeeper是個(gè)什么東西,大概能做些什么了,我們馬上來(lái)學(xué)習(xí)下zookeeper的安裝及使用,并開發(fā)一個(gè)小程序來(lái)實(shí)現(xiàn)zookeeper這個(gè)分布式配置管理的功能。
Step1:配置JAVA環(huán)境,檢驗(yàn)環(huán)境:java -version
Step2:下載并解壓zookeeper
# cd /usr/local# wget http://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz# tar -zxvf zookeeper-3.4.12.tar.gz# cd zookeeper-3.4.12
Step3:重命名配置文件zoo_sample.cfg
# cp conf/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
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、下面我們通過 set 命令來(lái)對(duì) zk 所關(guān)聯(lián)的字符串進(jìn)行設(shè)置:
6、下面我們將剛才創(chuàng)建的 znode 刪除
使用Java API操作zookeeper需要引用下面的包
下面我們來(lái)實(shí)現(xiàn)上面說的分布式配置中心:
1、在zookeeper里增加一個(gè)目錄節(jié)點(diǎn),并且把配置信息存儲(chǔ)在里面
2、啟動(dòng)兩個(gè)zookeeper客戶端程序,代碼如下所示
import java.util.concurrent.CountDownLatch;import org.apache.zookeeper.WatchedEvent;import org.apache.zookeeper.Watcher;import org.apache.zookeeper.Watcher.Event.EventType;import org.apache.zookeeper.Watcher.Event.KeeperState;import org.apache.zookeeper.ZooKeeper;import org.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 = new Stat(); public static void main(String[] args) throws Exception { //zookeeper配置數(shù)據(jù)存放路徑 String path = "/username"; //連接zookeeper并且注冊(cè)一個(gè)默認(rèn)的監(jiān)聽器 zk = new ZooKeeper("192.168.31.100:2181", 5000, // new ZooKeeperProSync()); //等待zk連接成功的通知 connectedSemaphore.await(); //獲取path目錄節(jié)點(diǎn)的配置數(shù)據(jù),并注冊(cè)默認(rèn)的監(jiān)聽器 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("配置已修改,新值為:" + new String(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ù)
修改完成后,我們看見兩個(gè)程序后臺(tái)都及時(shí)收到了他們監(jiān)聽的目錄節(jié)點(diǎn)數(shù)據(jù)變更后的值,如下所示
本例搭建的是偽集群模式,即一臺(tái)機(jī)器上啟動(dòng)三個(gè)zookeeper實(shí)例組成集群,真正的集群模式無(wú)非就是實(shí)例IP地址不同,搭建方法沒有區(qū)別
Step1:配置JAVA環(huán)境,檢驗(yàn)環(huán)境:java -version
Step2:下載并解壓zookeeper
# cd /usr/local# wget http://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz# tar -zxvf zookeeper-3.4.12.tar.gz# cd zookeeper-3.4.12
Step3:重命名 zoo_sample.cfg文件
# cp conf/zoo_sample.cfg conf/zoo-1.cfg
Step4:修改配置文件zoo-1.cfg,原配置文件里有的,修改成下面的值,沒有的則加上
# vim conf/zoo-1.cfgdataDir=/tmp/zookeeper-1clientPort=2181server.1=127.0.0.1:2888:3888server.2=127.0.0.1:2889:3889server.3=127.0.0.1:2890:3890
配置說明
tickTime:這個(gè)時(shí)間是作為 Zookeeper 服務(wù)器之間或客戶端與服務(wù)器之間維持心跳的時(shí)間間隔,也就是每個(gè) tickTime 時(shí)間就會(huì)發(fā)送一個(gè)心跳。
initLimit:這個(gè)配置項(xiàng)是用來(lái)配置 Zookeeper 接受客戶端(這里所說的客戶端不是用戶連接 Zookeeper 服務(wù)器的客戶端,而是 Zookeeper 服務(wù)器集群中連接到 Leader 的 Follower 服務(wù)器)初始化連接時(shí)最長(zhǎng)能忍受多少個(gè)心跳時(shí)間間隔數(shù)。當(dāng)已經(jīng)超過 10個(gè)心跳的時(shí)間(也就是 tickTime)長(zhǎng)度后 Zookeeper 服務(wù)器還沒有收到客戶端的返回信息,那么表明這個(gè)客戶端連接失敗??偟臅r(shí)間長(zhǎng)度就是 10*2000=20 秒
syncLimit:這個(gè)配置項(xiàng)標(biāo)識(shí) Leader 與 Follower 之間發(fā)送消息,請(qǐng)求和應(yīng)答時(shí)間長(zhǎng)度,最長(zhǎng)不能超過多少個(gè) tickTime 的時(shí)間長(zhǎng)度,總的時(shí)間長(zhǎng)度就是 5*2000=10秒
dataDir:顧名思義就是 Zookeeper 保存數(shù)據(jù)的目錄,默認(rèn)情況下,Zookeeper 將寫數(shù)據(jù)的日志文件也保存在這個(gè)目錄里。
clientPort:這個(gè)端口就是客戶端連接 Zookeeper 服務(wù)器的端口,Zookeeper 會(huì)監(jiān)聽這個(gè)端口,接受客戶端的訪問請(qǐng)求。
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不同即可
# cp conf/zoo-1.cfg conf/zoo-2.cfg# cp conf/zoo-1.cfg conf/zoo-3.cfg# vim conf/zoo-2.cfgdataDir=/tmp/zookeeper-2clientPort=2182# vim conf/zoo-2.cfgdataDir=/tmp/zookeeper-3clientPort=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 myid1# cd /tmp/zookeeper-2# vim myid2# cd /tmp/zookeeper-3# vim myid3
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è)
至此,我們對(duì)zookeeper就算有了一個(gè)入門的了解,當(dāng)然zookeeper遠(yuǎn)比我們這里描述的功能多,比如用zookeeper實(shí)現(xiàn)集群管理,分布式鎖,分布式隊(duì)列,zookeeper集群leader選舉等等。
想必大家對(duì)zookeeper有了一個(gè)了解吧!如果有更深層次的理解,歡迎在評(píng)論區(qū)和我討論討論!