Tips
做一個終身學習的人!
日拱一卒,功不唐捐。
在本節中,我們將講解如何下載並安裝Apache ZooKeeper,以便我們可以直接開始使用ZooKeeper。 本部分旨在通過提供詳細的安裝和使用說明,使用ZooKeeper了解其分布式應用程序的需求。 我們將從單節點ZooKeeper安裝開始,熟悉基本配置,然后學習ZooKeeper shell。 最后,學習如何設置一個多節點ZooKeeper集群。
1. 下載和安裝
ZooKeeper由各種平台支持。 支持GNU / Linux和Oracle Solaris作為服務器和客戶端的開發和生產平台。 Windows和Mac OS X系統僅推薦用作服務器和客戶端的開發平台。
ZooKeeper由Java中實現,需要運行Java 6或更高版本。 雖然推薦使用Oracle的Java版本,但OpenJDK也可以正常運行ZooKeeper。
ZooKeeper作為一個稱為ZooKeeper系列的服務器集合運行。 在生產集群中,三個ZooKeeper服務器是集合的最小建議大小,建議在不同的機器上運行它們。 但是,可以通過在獨立模式下將其安裝在單台計算機上來學習和練習ZooKeeper。
打開Apache ZooKeeper的官方網站,找到下載頁面的鏈接,根據自己的操作系統,選擇不同格式的文件,我用的macOS系統,所以下載了zookeeper-3.4.10.tar.gz,下載后,直接雙擊解壓即可。也可以使用命令:
tar -C /Users/i324779 -zxf zookeeper-3.4.10.tar.gz
我放在了當前用戶目錄下,你也根據自己的喜好放在指定的目錄下。
下載以后,我們需要配置一下環境變量:
以macOS為例,編輯用戶目錄下的.bash_profile
文件,添加如下:
export ZK_HOME=/Users/i324779/zookeeper-3.4.10 export PATH=$PATH:$ZK_HOME/bin
退出編輯后,在終端執行. .bash_profile
,立即生效。
接下來是配置, ZooKeeper在提取的ZooKeeper目錄下的conf目錄中需要一個名為zoo.cfg的配置文件。 在conf目錄下,有一個示例配置文件,其中包含一些配置參數供參考。
讓我們創建配置文件,並使用以下最小參數,並將其保存在conf目錄中:
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
配置參數的含義如下:
- tickTime:以毫秒為單位;用於會話注冊,並通過ZooKeeper服務為客戶定期進行心跳。 最小會話超時是tickTime參數的兩倍。
- dataDir:存儲ZooKeeper內存狀態的位置;它包括數據庫快照和數據庫更新的事務日志。 提取ZooKeeper目錄不會默認創建此目錄,因此如果系統中不存在此目錄,則需要創建該目錄並設置可寫權限。
- clientPort: 監聽客戶端連接的端口,因此它是ZooKeeper客戶端啟動連接的位置。 客戶端口可以設置為任意數字,不同的服務器可以配置為在不同端口上進行監聽。 默認值為2181。
如前所述,ZooKeeper需要一個Java運行時環境才能正常工作。所以,在運行ZooKeeper之前,需要安裝1.6版本以上的JDK。
2. 啟動ZooKeeper服務
所有ZooKeeper管理腳本啟動/停止服務器並調用ZooKeeper命令shell,並存放在bin目錄下:
$ pwd
/Users/i324779/zookeeper-3.4.10/bin
$ ls
README.txt zkCli.cmd zkEnv.cmd zkServer.cmd
zkCleanup.sh zkCli.sh zkEnv.sh zkServer.sh
擴展名為.sh的腳本適用於Unix平台(GNU / Linux,macOS等),擴展名為.cmd的腳本適用於Microsoft Windows操作系統。
要在GNU / Linux系統中啟動ZooKeeper服務器,需要執行如下的zkServer.s
h腳本。 此腳本提供啟動,停止,重新啟動並查看ZooKeeper服務器狀態的選項:
$ ./zkServer.sh
ZooKeeper JMX enabled by default
Using config: /Users/i324779/zookeeper-3.4.10/bin/../conf/zoo.cfg
Usage: ./zkServer.sh {start|start-foreground|stop|restart|status|upgrade|print-cmd}
執行zkServer.sh並加上start
參數將啟動ZooKeeper服務器。 服務器的成功啟動顯示以下輸出:
$ ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /Users/i324779/zookeeper-3.4.10/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
要驗證ZooKeeper服務器是否已啟動,可以使用以下ps
命令:
$ ps –ef | grep zookeeper | grep –v grep | awk '{print $2}'
56050
如果你的系統上安裝了jps命令,則可以如下驗證ZooKeeper服務器的狀態:
ps
56050 QuorumPeerMain
29942
53078
56072 Jps
ZooKeeper進程列為QuorumPeerMain
。 在這種情況下,執行jps命令顯示ZooKeeper服務器正在運行56050進程標識符,與ps命令報告的進程標識相匹配。
可以使用zkServer.sh腳本檢查ZooKeeper服務器的狀態,如下所示:
$ zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /Users/i32
要停止服務器進程,可以使用stop
參數的腳本:
$ zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /Users/i324779/zookeeper-3.4.10/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED
當ZooKeeper停止或不在運行時檢查狀態將顯示以下結果:
$ zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /Users/i324779/zookeeper-3.4.10/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED
一旦我們的ZooKeeper實例運行,接下來要做的就是連接到它。 ZooKeeper附帶默認的基於Java的命令行shell連接到ZooKeeper實例。 還有一個C語言版客戶端。
3. 使用基於Java的shell連接到ZooKeeper
要啟動基於Java的ZooKeeper命令行shell,我們只需要使用服務器IP和端口號運行ZK_HOME/bin目錄下的zkCli.sh,如下所示:
${ZK_HOME}/bin/zkCli.sh –server zk_server:port
在我們的例子中,我們在同一台機器上運行ZooKeeper服務器,所以ZooKeeper服務器是localhost,或者IP地址127.0.0.1。 配置的默認端口是2181:
$ zkCli.sh -server localhost:2181
當我們連接到運行的ZooKeeper實例時,將看到與終端中的以下輸出類似的輸出(部分有省略):
Connecting to localhost:2181
...............
...............
Welcome to ZooKeeper!
JLine support is enabled
...............
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 0]
要查看ZooKeeper Java shell支持的命令列表,可以在shell提示符下運行help
命令:
[zk: localhost:2181(CONNECTED) 0] help
ZooKeeper -server host:port cmd args
connect host:port
get path [watch]
ls path [watch]
set path data [version]
rmr path
delquota [-n|-b] path
quit
printwatches on|off
create [-s] [-e] path data acl
stat path [watch]
close
ls2 path [watch]
history
listquota path
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path [version]
setquota -n|-b val path
我們可以在命令行中執行一些簡單的命令,運行ls
命令,與Unix效果一樣:
[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper]
現在,ls
命令返回一個名為zookeeper
的字符串,它是ZooKeeper術語中的稱之為znode。 我們可以通過ZooKeeper shell創建一個znode,如下所示:
首先,創建一個空數據的HelloWorld
的znode:
[zk: localhost:2181(CONNECTED) 2] create /HelloWorld ""
Created /HelloWorld
[zk: localhost:2181(CONNECTED) 3] ls /
[zookeeper, HelloWorld]
可以使用delete
命令刪除創建的znode,如下所示:
[zk: localhost:2181(CONNECTED) 4] delete /HelloWorld
[zk: localhost:2181(CONNECTED) 5] ls /
[zookeeper]
4. 建立一個多節點ZooKeeper集群
到目前為止,我們已經在單機(standalone)模式下設置了一個ZooKeeper服務器實例。 單機實例存在潛在的單點故障。 如果ZooKeeper服務器出現故障,則使用該實例進行分布式協調的整個應用程序將失敗並停止運行。 因此,在實際生產環境中不推薦使用以單機模式運行ZooKeeper,盡管為了開發和測試的目的,是可以滿足需求的。
在生產環境中,ZooKeeper應該以復制模式運行在多台服務器上,也稱為ZooKeeper集合。 最低推薦的服務器數量是三個,五個是生產環境中最常見的。 同一應用程序域中的復制服務器組稱為quorum。 在此模式下,ZooKeeper服務器實例在多個不同的計算機上運行,quorum中的所有服務器都具有相同配置文件的副本。 在quorum中,ZooKeeper實例以領導者/跟隨者模式運行。 其中一個實例被選為領導者,其他成員則成為追隨者。 如果領導者失敗,就會出現新的領導者選舉,另一個正在執行的實例成為領導者。 然而,這些復雜性完全隱藏在使用ZooKeeper和開發人員的應用程序中。
用於多節點模式的ZooKeeper配置文件類似於我們用於單個實例模式的配置文件, 示例配置文件如下所示:
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888
這兩個配置參數也在這里說明一下:
- initLimit:這個參數是最初連接到領導者的跟隨者的超時時間,以毫秒數表示
- syncLimit:指定追隨者與領導者同步的超時時間
這兩個超時是以心跳時間為單位指定的。 因此,在我們的示例中,initLimit的超時時間為2000毫秒為一個心跳一共五次心跳,或10秒鍾。
server.id=host:port:port
格式的上述示例中的其他三個條目是構成quorum的服務器列表。 .id
標識符是一個數字,用於具有quorum主機名的服務器。 在我們的示例配置中,為zoo1
仲裁成員主機分配了一個標識符1
。
需要在該服務器的數據目錄中myid
的文件中指定標識符。 重要的是,myid
文件應該包含僅包含該服務器ID的文本(ASCII)的單行。 該集合中的id必須是唯一的,並且應該具有介於1到255之間的值。
還有,我們在每個服務器主機名后面有兩個端口號:2888和3888,這里解釋說明:
- 端口號2888,主要用於quorum中的對等通信,例如將追隨者與領導者聯系起來。一個追隨者使用這個端口打開一個到領導者的TCP連接。
- 端口號3888,用於領導者選舉,以防新領導者出現在仲裁中。由於所有的通信都發生在TCP上,因此需要第二個端口來響應仲裁內部的領導選舉。
5. 啟動服務實例
在為quorum中的每個服務器設置配置文件后,我們需要啟動ZooKeeper服務器實例。 該過程與單機模式相同。 我們必須連接到每個機器並執行以下命令:
${ZK_HOME}/bin/zkServer.sh start
一旦實例成功啟動,我們在每個機器上執行以下命令來檢查實例狀態:
${ZK_HOME}/bin/zkServer.sh status
例如,檢查下一個quorum:
[zoo1] # ${ZK_HOME}/bin/zkServer.sh status
JMX enabled by default
Using config: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: follower
[zoo2] # ${ZK_HOME}/bin/zkServer.sh status
JMX enabled by default
Using config: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: leader
[zoo3] # ${ZK_HOME}/bin/zkServer.sh status
JMX enabled by default
Using config: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: follower
如前面的例子所示,zoo2是quorum的領導者,而zoo1和zoo3是追隨者。 通過命令行shell連接到ZooKeeper的quorum與單機模式相同,除了在${ZK_HOME}/bin/zkCli.sh
命令中指定host1:port2, host2:port2 …
格式的連接字符串作為服務器的參數:
$ zkCli.sh -server zoo1:2181,zoo2:2181,zoo3:2181
Connecting to zoo1:2181, zoo2:2181, zoo3:2181
… … … …
Welcome to ZooKeeper!
… … … …
[zk: zoo1:2181,zoo2:2181,zoo3:2181 (CONNECTED) 0]
一旦ZooKeeper集群啟動並運行,就可以使用Java管理擴展(JMX)和通過客戶端口發送一些命令來監控它。
6. ZooKeeper運行多個節點模式
也可以在單台機器上以多節點模式運行ZooKeeper。 這對於測試目的很有用。 要在同一台機器上運行多節點模式,我們需要調整一下配置;例如,我們可以將服務器名稱設置為localhost,並指定唯一的quorum和領導者選舉端口。
我們使用以下配置文件,使用單台機器設置多節點ZooKeeper集群:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/var/lib/zookeeper
clientPort=2181
server.1=localhost:2666:3666
server.2=localhost:2667:3667
server.3=localhost:2668:3668
如上一節所述,服務器『X』的每個條目都指定『X』 ZooKeeper服務器使用的地址和端口號。 第一個字段是服務器『X』的主機名或IP地址。第二個和第三個字段分別是用於quorum通信和領導選舉的TCP端口號。 當我們在同一台機器上啟動三個ZooKeeper服務器實例時,我們需要為每個服務器條目使用不同的端口號。
其次,當我們在同一台機器上運行多個ZooKeeper服務器進程時,需要為每個實例提供不同的客戶端口。
還有,還要為每個正在運行的實例自定義dataDir
參數。
將所有這些參數放在一起,對於三個實例ZooKeeper集群,創建三個不同的配置文件。 將這些zoo1.cfg,zoo2.cfg和zoo3.cfg調用並保存在${ZK_HOME}
的conf目錄中。 為/var/lib/zookeeper
中的實例(例如zoo1,zoo2和zoo3)創建三個不同的數據目錄。 下面顯示三個配置文件。
以下是第一個實例的配置文件:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/var/lib/zookeeper/zoo1
clientPort=2181
server.1=localhost:2666:3666
server.2=localhost:2667:3667
server.3=localhost:2668:3668
第二個實例的配置文件:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/var/lib/zookeeper/zoo2
clientPort=2182
server.1=localhost:2666:3666
server.2=localhost:2667:3667
server.3=localhost:2668:3668
第三個也是最后一個配置文件:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/var/lib/zookeeper/zoo3
clientPort=2183
server.1=localhost:2666:3666
server.2=localhost:2667:3667
server.3=localhost:2668:3668
還需要在每個實例的myid文件中修復正確的服務ID參數。 可以使用以下三個命令完成:
$ echo 1 > /var/lib/zookeeper/zoo1/myid
$ echo 2 > /var/lib/zookeeper/zoo2/myid
$ echo 3 > /var/lib/zookeeper/zoo3/myid
現在,都設置為啟動ZooKeeper實例。 並開始運行以下實例:
$ ${ZK_HOME}/bin/zkServer.sh start ${ZK_HOME}/conf/zoo1.cfg
$ ${ZK_HOME}/bin/zkServer.sh start ${ZK_HOME}/conf/zoo2.cfg
$ ${ZK_HOME}/bin/zkServer.sh start ${ZK_HOME}/conf/zoo3.cfg
一旦所有的實例啟動完成,我們可以使用zkCli.sh腳本連接到多節點ZooKeeper集群,就像我們之前所做的那樣:
$ ${ZK_HOME}/bin/zkCli.sh –server \
localhost:2181, localhost:2182, localhost:2183
現在,我們有了運行在同一台機器上的三個節點ZooKeeper集群!