由淺入深Zookeeper詳解(參考官方文檔)

【老哥我最近接到個任務研究一下Zookeeper,對於我這個Linux運維領域的小菜鳥來講也是剛剛聽到這個名字,爲了養成良好的文檔整理和學習能力,我人生第一次開通了博客並把此次的研究經歷記錄了下來,之後我會不按期的記錄下來我對技術領域的探索,但願熱愛Linux運維志同道合的兄弟們多指教,一同進步成長。
(ps:我本人平時比較沉默,善於觀察思考,對歷史人物很有看法,可是一旦提及話來就會口若懸河,誰讓我曾經的夢想是當一名教師呢!哈哈!)
同時,送給你們一句話,人生是一場馬拉松比賽,只有堅持到最後的人,纔會讓人肅然起敬,並非由於他得到多大的成就,而是那知其不可爲而爲之的精神。】node

言歸正傳,學習一種新的技術首先固然是要拜訪Zookeeper的官方網站:http://zookeeper.apache.org/
軟件也是一種產品,而它的官方網站就是它的說明書,在這裏你能找到你所想要的東西。linux

分佈式系統
分佈式系統是由獨立的計算機經過網絡鏈接在一塊兒,而且經過一些組件來相互交流和協做來完成一個共同的目標。nginx

Zookeeper簡介
ZooKeeper是一個集中的服務,用於維護配置信息、命名、提供分佈式同步和提供組服務。全部這些服務都以某種形式由分佈式應用程序使用。每次實現它們時,都須要作大量工做來修復不可避免的bug和競爭條件。因爲難以實現這些服務,應用程序最初一般會節省這些服務,這使得它們在出現更改時變得脆弱,而且難以管理。即便處理正確,這些服務的不一樣實如今部署應用程序時也會致使管理複雜性。爲了解決這一問題,開發人員就研發出了Zookeeper。redis

1、Zookeeeper單機安裝及簡單操做
從https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.14/ 下載軟件
[root@8c649f93f3bc soft]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.14/
[root@8c649f93f3bc soft]# ls
Django-2.1.11 jdk-8u162-linux-x64.rpm redis-4.0.9
Django-2.1.11.tar.gz nginx-1.13.12 redis-4.0.9.tar.gz
install.sh nginx-1.13.12.tar.gz zookeeper-3.4.14.tar.gz算法

解壓軟件包,解壓後會生成一個zookeeper-3.4.14的目錄,進入目錄就會看到以下內容:
[root@8c649f93f3bc zookeeper-3.4.14]# ls
bin README.md zookeeper-client
build.xml README_packaging.txt zookeeper-contrib
conf src zookeeper-docs
dist-maven zoo1.cfg zookeeper-it
ivysettings.xml zoo2.cfg zookeeper-jute
ivy.xml zoo3.cfg zookeeper.out
lib zookeeper-3.4.14.jar zookeeper-recipes
LICENSE.txt zookeeper-3.4.14.jar.asc zookeeper-server
NOTICE.txt zookeeper-3.4.14.jar.md5
pom.xml zookeeper-3.4.14.jar.sha1數據庫

要啓動Zookeeper須要一個配置文件,建立配置文件conf/zoo.cfg
[root@8c649f93f3bc zookeeper-3.4.14]# cat conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/var/lib/zookeeper
clientPort=2181
下面是每一個字段的含義:
tickTime 單位爲微秒,用於session註冊和客戶端和ZooKeeper服務的心跳週期。session超時時長最小爲 tickTime的兩倍
dataDir :存儲內存中數據庫快照的位置,以及更新到數據庫的事務日誌(除非另有指定)。
clientPort: 監聽客戶機鏈接的端口,默認是2181express

啓動Zookeeper,因爲個人配置文件的相對路徑比較長,因此我對其作了個符號鏈接,以便操做
[root@8c649f93f3bc zookeeper-3.4.14]# ln -s conf/zoo.cfg zoo.cfg
此時就能夠指定配置文件啓動Zookeeper
[root@8c649f93f3bc zookeeper-3.4.14]# bin/zkServer.sh start zoo.cfg
ZooKeeper JMX enabled by default
Using config: /home/data/zookeeper/zookeeper-3.4.14/bin/../conf/zoo.cfg
Starting zookeeper ... already running as process 11614.
看到上述描述,就表示Zookeeper啓動成功。apache

查看Zookeeper的狀態
[root@8c649f93f3bc zookeeper-3.4.14]# bin/zkServer.sh status zoo.cfg
ZooKeeper JMX enabled by default
Using config: /home/data/zookeeper/zookeeper-3.4.14/bin/../conf/zoo.cfg
Mode: standalone
這裏能夠看到ZK的運行模式爲獨立的。緩存

對ZK進行管理,鏈接到zookeeper
[root@8c649f93f3bc zookeeper-3.4.14]# bin/zkCli.sh -server 127.0.0.1:2181
Connecting to 127.0.0.1:2181
敲一下help查看一下支持的命令
[zk: 127.0.0.1:2181(CONNECTED) 0] help
ZooKeeper -server host:port cmd args
stat path [watch]
set path data [version]
ls path [watch]
delquota [-n|-b] path
ls2 path [watch]
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version]
sync path
listquota path
rmr path
get path [watch]
create [-s] [-e] path data acl
addauth scheme auth
quit
getAcl path
close
connect host:port安全

經過運行create /zk_test my_data建立一個新的znode,這將建立一個新的znode並將字符串「my_data」與該節點關聯。
[zk: 127.0.0.1:2181(CONNECTED) 1] ls /
[zookeeper]

[zk: 127.0.0.1:2181(CONNECTED) 2] create /zk_test my_data
Created /zk_test

[zk: 127.0.0.1:2181(CONNECTED) 4] ls /
[zookeeper, zk_test]

接下來,運行get命令驗證數據是否與znode關聯,以下所示:
[zk: 127.0.0.1:2181(CONNECTED) 5] get /zk_test
my_data
cZxid = 0x6
ctime = Tue Aug 20 05:29:52 UTC 2019
mZxid = 0x6
mtime = Tue Aug 20 05:29:52 UTC 2019
pZxid = 0x6
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0

也能夠經過發出set命令來更改與zk_test關聯的數據
[zk: 127.0.0.1:2181(CONNECTED) 6] set /zk_test junk
cZxid = 0x6
ctime = Tue Aug 20 05:29:52 UTC 2019
mZxid = 0x7
mtime = Tue Aug 20 05:37:26 UTC 2019
pZxid = 0x6
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0

[zk: 127.0.0.1:2181(CONNECTED) 7] get /zk_test
junk
cZxid = 0x6
ctime = Tue Aug 20 05:29:52 UTC 2019
mZxid = 0x7
mtime = Tue Aug 20 05:37:26 UTC 2019
pZxid = 0x6
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0

最後,咱們能夠用以下命令刪除node
[zk: 127.0.0.1:2181(CONNECTED) 2] ls /
[zookeeper, zk_test]

[zk: 127.0.0.1:2181(CONNECTED) 3] delete /zk_test

[zk: 127.0.0.1:2181(CONNECTED) 4] ls /
[zookeeper]

2、瞭解了Zookeeper的單機安裝,下面咱們來了解一下Zookeeper的基本概念:

Zookeeper的數據模型
ZooKeeper有一個分層的名稱空間,很像一個分佈式文件系統。唯一的區別是名稱空間中的每一個節點均可以擁有與其關聯的數據和子節點。這就像一個文件系統容許一個文件同時也是一個目錄。節點的路徑老是表示爲規範的、絕對的、斜槓分隔的路徑;任何unicode字符都可在符合下列限制的路徑中使用:
1.null字符(\u0000)不能做爲路徑名的一部分。(這會致使C綁定出現問題。)
2.如下字符不能使用,由於它們不能很好地顯示,或者以使人困惑的方式呈現:\u0001 - \u001F和\u007F
3.\ u009F。
4.不容許使用如下字符:\ud800 - uF8FF, \uFFF0 - uFFFF。
5.「.」字符能夠用做另外一個名稱的一部分,可是「.」和「..」不能單獨用於指示路徑上的節點,由於ZooKeeper不使用相對路徑。下列內容無效:「/a/b/」。/ c」或「c / a / b / . . /」。
6.象徵性的「zookeeper」被保留。

ZNodes
ZooKeeper樹中的每一個節點都被稱爲znode。Znodes維護一個stat結構,其中包含數據更改、acl更改的版本號。stat結構還具備時間戳。版本號和時間戳容許ZooKeeper驗證緩存並協調更新。每次znode的數據發生變化,版本號就會增長。例如,每當客戶機檢索數據時,它也接收數據的版本。當客戶機執行更新或刪除操做時,它必須提供正在更改的znode數據的版本。若是它提供的版本與數據的實際版本不匹配,更新將失敗。
(在分佈式應用工程中,節點能夠指通常的主機、服務器、集成的成員、客戶機進程等。在ZooKeeper文檔中,znodes指的是數據節點。服務器是指構成Zookeeper服務的機器;仲裁對等點是指組成合集的服務器;客戶端是指任何使用ZooKeeper服務的主機或進程。)

znode有以下幾個特徵:

  1. Watches
    客戶端能夠在znode上設置watches。對該znode的更改將觸發watches,而後清除watches。當一個watches觸發時,ZooKeeper會向客戶端發送一個通知。
    2.數據訪問控制(Data Access)
    存儲在名稱空間中的每一個znode中的數據是原子式讀寫的。讀取獲取與znode關聯的全部數據字節,而寫入則替換全部數據。每一個節點都有一個訪問控制列表(ACL),用於限制誰能夠作什麼。(ZooKeeper並非一個通用數據庫或大型對象存儲庫。相反,它管理協調數據。這些數據能夠以配置、狀態信息、集合等形式出現。各類形式的協調數據的一個共同特性是它們相對較小:以千字節爲單位測量。ZooKeeper客戶機和服務器實現都進行了完整性檢查,以確保znode的數據少於1M,但平均數據應該比這少得多。在相對較大的數據大小上操做將致使某些操做比其餘操做花費更多的時間,若是須要大數據存儲,一般處理此類數據的模式是將其存儲在一個大存儲系統上,好比NFS或HDFS,並將指向ZooKeeper中存儲位置的指針存儲。)
    3.Ephemeral Nodes(臨時節點)
    ZooKeeper也有臨時節點的概念。只要建立znode的會話處於活動狀態,這些znode就會存在。當會話結束時,刪除znode。因爲這種行爲,臨時znode不容許有子節點。
    4.Sequence Nodes -- Unique Naming(順序節點)
    5.Container Nodes(容器節點) Added in 3.5.3
    ZooKeeper有容器znode的概念。容器znode是一種特殊用途的znode,可用於leader、lock等。當刪除容器的最後一個子元素時,容器將成爲未來某個時候服務器要刪除的候選對象。

Time in ZooKeeper
1.zxid 對ZooKeeper狀態的每次更改都會收到一個zxid (ZooKeeper事務Id)形式的戳記。這將向ZooKeeper公開全部更改的總順序。每一個更改都有一個唯一的zxid,若是zxid1小於zxid2,則zxid1發生在zxid2以前。
2.Version numbers 對節點的每一次更改都會致使該節點的版本號之一增長。這三個版本號是version(對znode數據的更改數量)、cversion(對znode子節點的更改數量)和hate(對znode ACL的更改數量)。
3.Ticks 當使用多服務器ZooKeeper時,服務器使用刻度來定義事件的時間,例如狀態上傳、會話超時、對等點之間的鏈接超時等。滴答時間僅經過最小會話超時(滴答時間的2倍)間接公開;若是客戶機請求的會話超時小於最小會話超時,服務器將告訴客戶機會話超時其實是最小會話超時。
4.Real time ZooKeeper根本不使用實時或時鐘時間,除了在znode建立和修改時將時間戳放入stat結構以外。

ZooKeeper Stat Structure
ZooKeeper中每一個znode的統計結構由如下字段組成:
1.czxid zxid的變化會致使這個節點被建立
2.mzxid 最後修改的zxid
3.pzxid 最後修改zxid的子節點
4.ctime 從建立znode開始的時間(以毫秒爲單位)。
5.mtime 此znode最後一次修改的時間(以毫秒爲單位)。
6.version 此znode的數據的更改數。
7.cversion 此znode的子節點的更改數。
8.aversion 更改此znode的ACL的次數。
9.ephemeralOwner 若是znode是臨時節點,則此znode全部者的會話id。若是不是臨時節點,則爲零。
10.dataLength 此znode的數據字段的長度。
11.numChildren 這個znode的子節點的個數。

ZooKeeper Sessions
ZooKeeper客戶端經過使用語言綁定建立服務句柄來與ZooKeeper服務創建會話。建立好句柄後,句柄將以鏈接狀態啓動,客戶端庫將嘗試鏈接到構成ZooKeeper服務的服務器之一,此時它將切換到鏈接狀態。在正常操做期間,客戶端句柄將處於這兩種狀態之一。若是出現不可恢復的錯誤,好比會話過時或身份驗證失敗,或者應用程序顯式關閉句柄,句柄將移動到關閉狀態。要建立一個客戶端會話,應用程序代碼必須提供一個鏈接字符串,其中包含一個逗號分隔的host:port對列表,每一個host:port對對應於ZooKeeper服務器(例如「127.0.0.1:4545」或「127.0.0.1:3000、127.0.0.1:3001 127.0.0.1:3002」)。ZooKeeper客戶端庫將選擇一個任意的服務器並嘗試鏈接到它。若是這個鏈接失敗,或者客戶機因爲任何緣由與服務器斷開鏈接,客戶機將自動嘗試列表中的下一個服務器,直到(從新)創建鏈接。在3.2.0版本後,還能夠在鏈接字符串後面附加一個可選的「chroot」後綴。這將運行客戶機命令,同時解釋與此根相關的全部路徑(相似於unix chroot命令)。若是使用示例的樣子:「127.0.0.1:4545 / app /」或「127.0.0.1:3000、127.0.0.1:3001 127.0.0.1:3002 / app /「客戶端將紮根在/ app /和全部路徑是相對於這個根——即root - ie getting/setting/etc... "/foo/bar"將致使在「/app/a/foo/bar」上運行操做(從服務器的角度來看)。這個特性在多租戶環境中特別有用,在多租戶環境中,特定ZooKeeper服務的每一個用戶均可以有不一樣的根。這使得重用更加簡單,由於每一個用戶均可以編寫他/她的應用程序,就像它植根於「/」同樣,而實際位置(好比/app/a)能夠在部署時肯定。
當客戶端得到ZooKeeper服務的句柄時,ZooKeeper建立一個ZooKeeper會話(表示爲64位數字),並將其分配給客戶端。若是客戶機鏈接到另外一個ZooKeeper服務器,它將發送會話id做爲鏈接握手的一部分。做爲安全措施,服務器爲任何ZooKeeper服務器均可以驗證的會話id建立一個密碼。當客戶端創建會話時,密碼將與會話id一塊兒發送給客戶端。每當客戶機使用新服務器從新創建會話時,它就用會話id發送這個密碼。
建立ZooKeeper會話的ZooKeeper客戶端庫調用的參數之一是會話超時(以毫秒爲單位)。客戶機發送一個請求的超時,服務器用它能夠給客戶機的超時進行響應。當前實現要求超時時間最少爲tickTime的2倍(在服務器配置中設置),最多爲tickTime的20倍。ZooKeeper客戶端API容許訪問協商超時。
當客戶機(會話)從ZK服務集羣中分區時,它將開始搜索會話建立期間指定的服務器列表。最終,當客戶機和至少一個服務器之間的鏈接被從新創建時,會話將再次過渡到「connected」狀態(若是在會話超時值內從新鏈接),或者過渡到「expired」狀態(若是在會話超時以後從新鏈接)。不建議建立一個用於斷開鏈接的新會話對象(一個新的zookeeper .class或c綁定中的zookeeper句柄)。ZK客戶端庫將爲您處理從新鏈接。特別是,咱們在客戶端庫中構建了啓發式來處理諸如「羊羣效應」等問題。只有當您被通知會話過時(強制)時才建立一個新會話。
會話過時由ZooKeeper集羣自己管理,而不是由客戶機管理。當ZK客戶機與集羣創建一個會話時,它提供了上面詳細描述的「超時」值。集羣使用此值來肯定客戶機的會話什麼時候過時。當集羣在指定的會話超時期間(即沒有心跳)內沒有收到客戶機的消息時,就會發生終止。在會話過時時,集羣將刪除該會話擁有的任何/全部臨時節點,並當即通知任何/全部鏈接的客戶機更改(任何監視這些znode的人)。此時,過時會話的客戶機仍然與集羣斷開鏈接,直到/除非它可以從新創建到集羣的鏈接,不然不會通知它會話過時。客戶機將保持斷開鏈接狀態,直到使用集羣從新創建TCP鏈接,此時過時會話的監視程序將收到「會話過時」通知。
ZooKeeper會話創建調用的另外一個參數是默認的監視程序。當客戶機中發生任何狀態更改時,會通知監視者。例如,若是客戶端失去與服務器的鏈接,客戶端將獲得通知,或者若是客戶端會話過時,等等。此監視程序應該考慮斷開初始狀態(即在任何狀態更改事件由客戶端庫發送到監視程序以前)。在新鏈接的狀況下,發送給觀察者的第一個事件一般是會話鏈接事件。
會話經過客戶機發送的請求保持活動狀態。若是會話空閒一段時間會超時會話,客戶端將發送一個PING請求來保持會話活動。這個PING請求不只容許ZooKeeper服務器知道客戶機仍然處於活動狀態,並且還容許客戶機驗證它到ZooKeeper服務器的鏈接是否仍然處於活動狀態。PING的時間足夠保守,能夠確保有合理的時間檢測死鏈接並從新鏈接到新服務器。
一旦成功創建到服務器的鏈接(鏈接)基本上有兩個狀況下,客戶端自由生成connectionloss(結果用c代碼綁定,用Java異常,請查看API文檔綁定具體細節)當執行一個同步或異步操做,下列是適用的:
1.應用程序調用再也不有效的會話上的操做
2.當服務器上有掛起的操做時,ZooKeeper客戶端斷開與服務器的鏈接,有一個掛起的異步調用。

Updating the list of servers 更新服務器列表:容許客戶端經過提供一個新的逗號分隔的host:port對列表來更新鏈接字符串,每一個host:port對對應於ZooKeeper服務器。該函數調用一個機率負載平衡算法,該算法可能致使客戶端與其當前主機斷開鏈接,目標是在新列表中實現每一個服務器預期的統一鏈接數。若是客戶端鏈接到的當前主機不在新列表中,此調用將始終致使鏈接被刪除。不然,則根據serv的數量來決定。例如,若是之前的鏈接字符串包含3臺主機,而如今列表包含這3臺主機和另外2臺主機,那麼鏈接到這3臺主機的40%的客戶端將移動到其中一臺新主機,以平衡負載。該算法將致使客戶端斷開與當前主機的鏈接,該鏈接的機率爲0.4,在本例中,將致使客戶端鏈接到隨機選擇的兩個新主機之一。另外一個例子,假設咱們有5如今主機和主機的更新列表,刪除2,剩下的客戶端鏈接到3主機將保持聯繫,而全部客戶機鏈接到2刪除主機須要搬到一個3主機,隨機選取的。若是鏈接被刪除,客戶端將切換到一種特殊模式,在這種模式中,他將使用機率算法選擇新服務器鏈接,而不只僅是循環。在第一個示例中,每一個客戶機決定斷開鏈接的機率爲0.4,可是一旦作出了這個決定,它將嘗試鏈接到一個隨機的新服務器,只有當它不能鏈接到任何一個新服務器時,它才嘗試鏈接到舊服務器。在找到一個服務器以後,或者嘗試新列表中的全部服務器,可是鏈接失敗以後,客戶機返回到正常的操做模式,從connectString中選擇一個任意的服務器,並嘗試鏈接到它。若是失敗,它將繼續在輪詢中嘗試不一樣的隨機服務器。

ZooKeeper Watches
1.當數據發生變化時,將向客戶端發送一次觸發One watch事件。例如,若是客戶機執行getData("/znode1", true),而後更改或刪除/znode1的數據,客戶機將得到/znode1的watch事件。若是/znode1再次更改,則不會發送任何watch事件,除非客戶端完成了設置新Watches的另外一次讀取。
2.發送到客戶端意味着一個事件正在發送到客戶端途中,可是在成功地將更改操做的返回代碼發送到發起更改的客戶端以前,可能沒法到達客戶端。手錶以異步方式發送給觀察者。ZooKeeper提供了一個訂購保證:客戶端在第一次看到watch事件以前,永遠不會看到設置了Watches的更改。網絡延遲或其餘因素可能致使不一樣的客戶端在不一樣的時間看到Watches並從更新中返回代碼。關鍵是不一樣客戶看到的全部東西都有一個一致的順序。

  1. Watches在客戶機鏈接到的ZooKeeper服務器上本地維護。這使得 Watches的設置、維護和分派都很輕量。當客戶端鏈接到新服務器時,將爲任何會話事件觸發 Watches。當與服務器斷開鏈接時,將不會接收到 Watches。當客戶端從新鏈接時,任何之前註冊的 Watches都將從新註冊並在須要時觸發。通常來講,這一切都是透明的。有一種狀況下可能會錯過一個 Watches:若是建立了znode,則會錯過一個還沒有建立znode的 Watches。
    關於Watches的注意事項:
    1.Watches是一次性觸發器;若是您得到了一個watch事件,而且但願獲得關於將來更改的通知,則必須設置另外一個watch。
    2.由於Watches是一次性觸發器,而且在獲取事件和發送獲取Watches的新請求之間存在延遲,因此您不能可靠地查看ZooKeeper中節點發生的每一個更改。準備處理znode在獲取事件和再次設置Watches之間屢次更改的狀況。(你可能不在意,但至少意識到它可能會發生。)
    3.對於給定的通知,監視對象或函數/上下文對只會觸發一次。例如,若是爲exists註冊了相同的watch對象,而且爲相同的文件調用了getData,而後刪除了該文件,那麼使用該文件的刪除通知只會調用該watch對象一次。
    4.當斷開與服務器的鏈接時(例如,當服務器失敗時),在從新創建鏈接以前,不會獲得任何Watches。所以,會話事件被髮送給全部未完成的Watches處理程序。使用會話事件進入安全模式:斷開鏈接時不會接收事件,所以您的流程應該在該模式下謹慎地工做。

ZooKeeper access control using ACLs
ZooKeeper使用acl控制對其znode (ZooKeeper數據樹的數據節點)的訪問。ACL實現與UNIX文件訪問權限很是類似:它使用權限位容許/不容許對節點和應用這些位的範圍執行各類操做。與標準UNIX權限不一樣,ZooKeeper節點不受user(文件全部者)、group和world(其餘)三個標準範圍的限制。ZooKeeper沒有znode的全部者的概念。相反,ACL指定與這些id關聯的id和權限集。
還要注意,ACL只屬於特定的znode。它尤爲不適用於兒童。例如,若是/app只能經過ip:172.16.16.1讀取,而/app/status是世界可讀的,那麼任何人均可以讀取/app/status;acl不是遞歸的。
ZooKeeper支持可插入的身份驗證方案。id使用表單scheme:expression指定,其中scheme是id對應的身份驗證方案。該方案定義了一組有效表達式。例如,ip:172.16.16.1是使用ip方案的地址爲172.16.16.1的主機的id,而digest:bob:password是使用摘要方案的用戶的id,其名稱爲bob。
當客戶端鏈接到ZooKeeper並驗證自身時,ZooKeeper將與客戶端鏈接對應的全部id關聯起來。當客戶機試圖訪問某個節點時,將根據znodes的acl檢查這些id。acl由一對(scheme:expression, perms)組成。表達式的格式是特定於方案的。例如,這對(ip:19.22.0.0/16, READ)將讀權限授予ip地址以19.22開頭的任何客戶機。
ZooKeeper支持如下權限:
CREATE: you can create a child node
READ: you can get data from a node and list its children.
WRITE: you can set data for a node
DELETE: you can delete a child node
ADMIN: you can set permissions

3、Zookeeper集羣的搭建
前面我講解了ZK的單機搭建,如今講解一下ZK集羣的搭建,咱們以三個節點的集羣爲例,因爲沒有真實環境條件,只能在一臺主機上搭建三個節點的僞集羣,集羣搭建過程當中要注意幾個點,下面我會逐一進行說明。
用第一節講解的環境進行下一步操做,首先再建立三個配置文件,因爲路徑的緣由,我對這三個配置文件分別作了符號鏈接,文件內容以下:
[root@8c649f93f3bc zookeeper-3.4.14]# cat zoo1.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/var/lib/zookeeper/zoo1
clientPort=2182
server.1=localhost:2666:3666
server.2=localhost:2667:3667
server.3=localhost:2668:3668
[root@8c649f93f3bc zookeeper-3.4.14]# cat zoo2.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/var/lib/zookeeper/zoo2
clientPort=2183
server.1=localhost:2666:3666
server.2=localhost:2667:3667
server.3=localhost:2668:3668
[root@8c649f93f3bc zookeeper-3.4.14]# cat zoo3.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/var/lib/zookeeper/zoo3
clientPort=2184
server.1=localhost:2666:3666
server.2=localhost:2667:3667
server.3=localhost:2668:3668
須要說明的是,每一個配置文件的端口號和dataDir不要重複,server.no=ip:port1:port2 ,其中no爲集羣的標識符,ip爲主機地址,port1爲集羣內部通信的端口,port2爲集羣內部選舉leader的端口。
而後在數據目錄/var/lib/zookeeper/zoo3下建立myid文件,文件的內容和你的server id 保持一致,不然啓動時會報錯,內容以下:
[root@8c649f93f3bc zoo1]# cat myid
1
[root@8c649f93f3bc zoo2]# cat myid
2
[root@8c649f93f3bc zoo3]# cat myid
3

編輯好配置文件就能夠啓動服務了,以下所示:
[root@8c649f93f3bc zookeeper-3.4.14]# bin/zkServer.sh start zoo1.cfg
ZooKeeper JMX enabled by default
Using config: /home/data/zookeeper/zookeeper-3.4.14/bin/../conf/zoo1.cfg
Starting zookeeper ... STARTED
[root@8c649f93f3bc zookeeper-3.4.14]# bin/zkServer.sh start zoo2.cfg
ZooKeeper JMX enabled by default
Using config: /home/data/zookeeper/zookeeper-3.4.14/bin/../conf/zoo2.cfg
Starting zookeeper ... STARTED
[root@8c649f93f3bc zookeeper-3.4.14]# bin/zkServer.sh start zoo3.cfg
ZooKeeper JMX enabled by default
Using config: /home/data/zookeeper/zookeeper-3.4.14/bin/../conf/zoo3.cfg
Starting zookeeper ... STARTED

查看集羣各個節點的狀態及所處的模式,以下所示
[root@8c649f93f3bc zookeeper-3.4.14]# bin/zkServer.sh status zoo1.cfg
ZooKeeper JMX enabled by default
Using config: /home/data/zookeeper/zookeeper-3.4.14/bin/../conf/zoo1.cfg
Mode: follower
[root@8c649f93f3bc zookeeper-3.4.14]# bin/zkServer.sh status zoo2.cfg
ZooKeeper JMX enabled by default
Using config: /home/data/zookeeper/zookeeper-3.4.14/bin/../conf/zoo2.cfg
Mode: leader
[root@8c649f93f3bc zookeeper-3.4.14]# bin/zkServer.sh status zoo3.cfg
ZooKeeper JMX enabled by default
Using config: /home/data/zookeeper/zookeeper-3.4.14/bin/../conf/zoo3.cfg
Mode: follower
官方文檔給的建議是主機的數量是奇數(2n+1),集羣中容許壞的最多數量爲n個。

以上就是對Zookeeper的簡單介紹,知識點很雜,有些較爲難理解,若是感興趣的話,就去讀官方的英文文檔,下篇文章見,拜拜!

相關文章
相關標籤/搜索