1. 程式人生 > >Zookeeper介紹及安裝部署

Zookeeper介紹及安裝部署

 一、Zookeeper介紹
    是一個針對大型分散式系統的可靠協調系統;
    提供的功能包括:配置維護、名字服務、分散式同步、組服務等;
    目標就是封裝好複雜易出錯的關鍵職務,將簡單易用的介面和效能高效、功能穩定的系統提供給使用者;
    Zookeeper已經成為Hadoop生態系統中的基礎元件。
二、Zookeeper特點
    最終一致性:為客戶端展示同一檢視,這是Zookeeper最重要的效能;
    可靠性:如果訊息被一臺伺服器接受,那麼它將被所有的伺服器接受;
    原子性:更新只能成功或失敗,沒有中間狀態;
三、Zookeeper應用場景
1. 統一命名服務
(1)分散式環境下,經常需要對應用/服務進行統一命名,便於識別不同的服務
    類似於域名與ip之間對應關係,域名容易記住;
    通過名稱來獲取資源或服務的地址,提供者資訊。
(2)按照層次結構組織服務/應用名稱
    可將服務名稱以及地址資訊寫在Zookeeper上,客戶端通過Zookeeper獲取可用服務列表。
2. 配置管理
(1)分散式環境下,配置檔案管理和同步是一個常見問題
    一個叢集中,所有節點的配置資訊是一致的,比如Hadoop;
    對配置檔案修改後,希望能夠快速同步到各個節點上。
(2)配置管理可交由Zookeeper實現
    可將配置資訊寫入Zookeeper的一個znode上;
    各個節點監聽這個znode
    一旦znode中的資料被修改,Zookeeper將會通知各個節點。
3. 叢集管理
(1)分散式環境下,實時掌握每個節點的狀態是必要的
    可根據節點實時狀態做出一些調整。
(2)可交由Zookeeper實現
    可將節點資訊寫入Zookeeper的一個znode上;
    監聽這個znode可獲得它的實時狀態變化。
(3)典型應用
    HBase中Master狀態的監控與選舉。
4. 分散式通知/協調
原理其實就是釋出/訂閱。
(1)分散式環境下經常存在一個服務需要知道它所管理的子服務的狀態
    NameNode需要知道各DataNode的狀態
(2)心跳檢測機制可通過Zookeeper實現
(3)資訊推送可由Zookeeper實現(釋出/訂閱模式)
5. 分散式鎖
(1)Zookeeper是強一致性的
    多個客戶端同時在Zookeeper上建立相同znode,只有一個建立成功。
(2)實現鎖的獨佔性
    多個客戶端同時在Zookeeper上建立相同znode,建立成功的那個客戶端得到鎖,其他客戶端等待。
(3)控制鎖的時序
    各個客戶端在某個znode下建立臨時znode(型別為CreateMode.EPHEMERAL_SEQUENTIAL),這樣,該znode可掌握全域性訪問時序。
四、用到了Zookeeper的一些系統
    HDFS
    YARN
    Storm
    HBase
    Flume
    Dubbo
    metaq
五、Zookeeper叢集安裝部署
下面開始介紹Zookeeper的安裝部署。安裝部署分三種模式:單機模式、偽分散式模式和分散式模式。單機模式和偽分散式比較簡單,多用於本地測試除錯,下面介紹分散式模式安裝部署。
注意:3臺機器都需要安裝zk。對於Zookeeper叢集的話,官方推薦的最小節點數為3個。
1. 環境資訊
主機名     作業系統版本     IP地址     安裝軟體
console     CentOS 7.0     114.55.29.246     JDK1.7、zookeeper-3.4.6
log1     CentOS 7.0     114.55.29.86     JDK1.7、zookeeper-3.4.6
log2     CentOS 7.0     114.55.29.241     JDK1.7、zookeeper-3.4.6
2. 安裝jdk1.7
3臺機器都需要安裝jdk1.7
[

[email protected] local]# mkdir /usr/java
[[email protected] local]# tar zxf jdk-7u80-linux-x64.gz -C /usr/java/
[[email protected] local]# vim /etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_80
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
[[email protected]
local]# source /etc/profile
3. 安裝配置zk
(1)配置zk節點的hosts檔案:配置3臺機器的ip地址和主機名的對應關係。以下以console主機為例,其hosts檔案新增下面3行:
114.55.29.246 console
114.55.29.86 log1
114.55.29.241 log2

(2)解壓安裝配置第一臺zk
[[email protected] local]# tar zxf zookeeper-3.4.6.tar.gz
[[email protected] local]# cd zookeeper-3.4.6

建立快照日誌存放目錄:
[
[email protected]
zookeeper-3.4.6]# mkdir -p dataDir

建立事務日誌存放目錄:
[[email protected] zookeeper-3.4.6]# mkdir dataLogDir

【注意】:如果不配置dataLogDir,那麼事務日誌也會寫在dataDir目錄中。這樣會嚴重影響zk的效能。因為在zk吞吐量很高的時候,產生的事務日誌和快照日誌太多。

修改配置檔案,新增如下內容:

[[email protected] zookeeper-3.4.6]# cd conf
[[email protected] conf]# mv zoo_sample.cfg zoo.cfg

[[email protected]sole conf]# vim zoo.cfg

# 存放資料檔案
dataDir=/usr/local/zookeeper-3.4.6/dataDir

# 存放日誌檔案
dataLogDir=/usr/local/zookeeper-3.4.6/dataLogDir

# zookeeper cluster,2888為選舉埠,3888為心跳埠

server.1=console:2888:3888
server.2=log1:2888:3888
server.3=log2:2888:3888


在我們配置的dataDir指定的目錄下面,建立一個myid檔案,
裡面內容為一個數字,用來標識當前主機,
conf/zoo.cfg檔案中配置的server.X中X為什麼數字,則myid檔案中就輸入這個數字:

[[email protected] ~]# echo "1" > /usr/local/zookeeper-3.4.6/dataDir/myid


(3)遠端複製第一臺的zk到另外兩臺上,並修改myid檔案為2和3

[[email protected] local]# scp -rp zookeeper-3.4.6 [email protected]:/usr/local/
[[email protected] local]# scp -rp zookeeper-3.4.6 [email protected]:/usr/local/
 

4. 啟動和關閉zk

在ZooKeeper叢集的每個結點上,執行啟動ZooKeeper服務的指令碼,如下所示:

[[email protected] bin]# ./zkServer.sh start
[[email protected] bin]# ./zkServer.sh start
[[email protected] bin]# ./zkServer.sh start

日誌可查詢:/usr/local/zookeeper-3.4.6/bin/zookeeper.out


可以通過命令jps檢視Zookeeper程序:


停止zk命令:

# /usr/local/zookeeper-3.4.6/bin/zkServer.sh stop

5. 測試zk叢集

可以通過ZooKeeper的指令碼來檢視啟動狀態,包括叢集中各個結點的角色(或是Leader,或是Follower)

[[email protected] bin]# ./zkServer.sh status
JMX enabled by default
Using config: /usr/local/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: follower

[[email protected] bin]# ./zkServer.sh status
JMX enabled by default
Using config: /usr/local/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: leader

[[email protected] bin]# ./zkServer.sh status
JMX enabled by default
Using config: /usr/local/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: follower


通過上面狀態查詢結果可見,log1是叢集的Leader,其餘的兩個結點是Follower。


另外,可以通過客戶端指令碼,連線到ZooKeeper叢集上。對於客戶端來說,ZooKeeper是一個整體,連線到ZooKeeper叢集實際上感覺在獨享整個叢集的服務,所以,你可以在任何一個結點上建立到服務叢集的連線。


[[email protected] bin]# ./zkCli.sh -server log1:2181

Connecting to log1:2181
2016-03-08 14:21:31,502 [myid:] - INFO  [main:[email protected]] - Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT
2016-03-08 14:21:31,505 [myid:] - INFO  [main:[email protected]] - Client environment:host.name=log2
2016-03-08 14:21:31,505 [myid:] - INFO  [main:[email protected]] - Client environment:java.version=1.7.0_80
2016-03-08 14:21:31,507 [myid:] - INFO  [main:[email protected]] - Client environment:java.vendor=Oracle Corporation
2016-03-08 14:21:31,507 [myid:] - INFO  [main:[email protected]] - Client environment:java.home=/usr/java/jdk1.7.0_80/jre
2016-03-08 14:21:31,507 [myid:] - INFO  [main:[email protected]] - Client environment:java.class.path=/usr/local/zookeeper-3.4.6/bin/../build/classes:/usr/local/zookeeper-3.4.6/bin/../build/lib/*.jar:/usr/local/zookeeper-3.4.6/bin/../lib/slf4j-log4j12-1.6.1.jar:/usr/local/zookeeper-3.4.6/bin/../lib/slf4j-api-1.6.1.jar:/usr/local/zookeeper-3.4.6/bin/../lib/netty-3.7.0.Final.jar:/usr/local/zookeeper-3.4.6/bin/../lib/log4j-1.2.16.jar:/usr/local/zookeeper-3.4.6/bin/../lib/jline-0.9.94.jar:/usr/local/zookeeper-3.4.6/bin/../zookeeper-3.4.6.jar:/usr/local/zookeeper-3.4.6/bin/../src/java/lib/*.jar:/usr/local/zookeeper-3.4.6/bin/../conf:.:/usr/java/jdk1.7.0_80/lib/dt.jar:/usr/java/jdk1.7.0_80/lib/tools.jar
2016-03-08 14:21:31,507 [myid:] - INFO  [main:[email protected]] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2016-03-08 14:21:31,508 [myid:] - INFO  [main:[email protected]] - Client environment:java.io.tmpdir=/tmp
2016-03-08 14:21:31,508 [myid:] - INFO  [main:[email protected]] - Client environment:java.compiler=
2016-03-08 14:21:31,508 [myid:] - INFO  [main:[email protected]] - Client environment:os.name=Linux
2016-03-08 14:21:31,508 [myid:] - INFO  [main:[email protected]] - Client environment:os.arch=amd64
2016-03-08 14:21:31,508 [myid:] - INFO  [main:[email protected]] - Client environment:os.version=3.10.0-123.9.3.el7.x86_64
2016-03-08 14:21:31,508 [myid:] - INFO  [main:[email protected]] - Client environment:user.name=root
2016-03-08 14:21:31,508 [myid:] - INFO  [main:[email protected]] - Client environment:user.home=/root
2016-03-08 14:21:31,508 [myid:] - INFO  [main:[email protected]] - Client environment:user.dir=/usr/local/zookeeper-3.4.6/bin
2016-03-08 14:21:31,510 [myid:] - INFO  [main:[email protected]] - Initiating client connection, connectString=log1:2181 sessionTimeout=30000 [email protected]
Welcome to ZooKeeper!
2016-03-08 14:21:31,534 [myid:] - INFO  [main-SendThread(log1:2181):[email protected]] - Opening socket connection to server log1/114.55.29.86:2181. Will not attempt to authenticate using SASL (unknown error)
2016-03-08 14:21:31,539 [myid:] - INFO  [main-SendThread(log1:2181):[email protected]] - Socket connection established to log1/114.55.29.86:2181, initiating session
JLine support is enabled
[zk: log1:2181(CONNECTING) 0] 2016-03-08 14:21:31,572 [myid:] - INFO  [main-SendThread(log1:2181):[email protected]] - Session establishment complete on server log1/114.55.29.86:2181, sessionid = 0x25354db0d430000, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null

[zk: log1:2181(CONNECTED) 0]

6. 指令碼定期清理zk快照和日誌檔案

正常執行過程中,ZK會不斷地把快照資料和事務日誌輸出到dataDir和dataLogDir這兩個目錄,並且如果沒有人為操作的話,ZK自己是不會清理這些檔案的。 我這裡採用指令碼切割。

[[email protected] ~]# cd /usr/local/zookeeper-3.4.6/

[[email protected] zookeeper-3.4.6]# vim clean_zklog.sh
#!/bin/bash

# Snapshot file dir.
dataDir=/usr/local/zookeeper-3.4.6/dataDir/version-2

# Transaction logs dir.
dataLogDir=/usr/local/zookeeper-3.4.6/dataLogDir/version-2

# Reserved 5 files.
COUNT=5

ls -t $dataDir/snapshot.* | tail -n +$[$COUNT+1] | xargs rm -f

ls -t $dataLogDir/log.* | tail -n +$[$COUNT+1] | xargs rm -f

[[email protected] zookeeper-3.4.6]# chmod +x clean_zklog.sh

每個Zookeeper叢集節點配置週期性任務,每個星期日的0點0分執行:

[[email protected] zookeeper-3.4.6]# crontab -e
0 0 * * 0 /usr/local/zookeeper-3.4.6/clean_zklog.sh


zookeeper有單機、偽叢集、叢集三種部署方式,可根據自己對可靠性的需求選擇合適的部署方式。下邊對這三種部署方式逐一進行講解。

一、單機安裝

1.1 下載

進入要下載的版本的目錄,選擇.tar.gz檔案下載

下載連結:http://archive.apache.org/dist/zookeeper/

1.2 安裝

使用tar解壓要安裝的目錄即可,以3.4.5版本為例

這裡以解壓到/usr/myapp,實際安裝根據自己的想安裝的目錄修改(注意如果修改,那後邊的命令和配置檔案中的路徑都要相應修改)

tar -zxf zookeeper-3.4.5.tar.gz -C /usr/myapp
 
1.3 配置

在主目錄下建立data和logs兩個目錄用於儲存資料和日誌:

cd /usr/myapp/zookeeper-3.4.5
mkdir data
mkdir logs
 
在conf目錄下新建zoo.cfg檔案,寫入以下內容儲存:


tickTime=2000
dataDir=/usr/myapp/zookeeper-3.4.5/data
dataLogDir=/usr/myapp/zookeeper-3.4.5/logs
clientPort=2181
 
1.4 啟動和停止

進入bin目錄,啟動、停止、重啟分和檢視當前節點狀態(包括叢集中是何角色)別執行:

./zkServer.sh start
./zkServer.sh stop
./zkServer.sh restart
./zkServer.sh status
 
二、偽叢集模式

偽叢集模式就是在同一主機啟動多個zookeeper並組成叢集,下邊以在192.168.220.128主機上創3個zookeeper組叢集為例。

將通過第一大點安裝的zookeeper,複製成zookeeper1/zookeeper2/zookeeper3三份

2.1 zookeeper1配置

zookeeper1配置檔案conf/zoo.cfg修改如下:

tickTime=2000
dataDir=/usr/myapp/zookeeper1/data
dataLogDir=/usr/myapp/zookeeper1/logs
clientPort=2181
initLimit=5
syncLimit=2
server.1=192.168.220.128:2888:3888
server.2=192.168.220.128:4888:5888
server.3=192.168.220.128:6888:7888

zookeeper1的data/myid配置如下:

echo '1' > data/myid
 
2.2 zookeeper2配置

zookeeper2配置檔案conf/zoo.cfg修改如下:

tickTime=2000
dataDir=/usr/myapp/zookeeper2/data
dataLogDir=/usr/myapp/zookeeper2/logs
clientPort=3181
initLimit=5
syncLimit=2
server.1=192.168.220.128:2888:3888
server.2=192.168.220.128:4888:5888
server.3=192.168.220.128:6888:7888

zookeeper2的data/myid配置如下:

echo '2' > data/myid
 
2.3 zookeeper3配置

zookeeper3配置檔案conf/zoo.cfg修改如下:

tickTime=2000
dataDir=/usr/myapp/zookeeper3/data
dataLogDir=/usr/myapp/zookeeper3/logs
clientPort=4181
initLimit=5
syncLimit=2
server.1=192.168.220.128:2888:3888
server.2=192.168.220.128:4888:5888
server.3=192.168.220.128:6888:7888

 zookeeper3的data/myid配置如下:

echo '3' > data/myid

最後使用1.4的命令把三個zookeeper都啟動即可,啟動順序隨意沒要求。

三、叢集模式

叢集模式就是在不同主機上安裝zookeeper然後組成叢集的模式;下邊以在

192.168.220.128/129/130三臺主機為例。

將第1.1到1.3步中安裝好的zookeeper打包複製到129和130上,並都解壓到同樣的目錄下。

3.1 conf/zoo.cfg檔案修改

三個zookeeper的conf/zoo.cfg修改如下:

tickTime=2000
dataDir=/usr/myapp/zookeeper-3.4.5/data
dataLogDir=/usr/myapp/zookeeper-3.4.5/logs
clientPort=2181
initLimit=5
syncLimit=2
server.1=192.168.220.128:2888:3888
server.2=192.168.220.129:2888:3888
server.3=192.168.220.130:2888:3888

對於129和130,由於安裝目錄都是zookeeper-3.4.5所以dataDir和dataLogDir不需要改變,又由於在不同機器上所以clientPort也不需要改變

所以此時129和130的conf/zoo.cfg的內容與128一樣即可。

3.2 data/myid檔案修改

128 data/myid修改如下:

echo '1' > data/myid

129 data/myid修改如下:

echo '2' > data/myid
130 data/myid修改如下:

echo '3' > data/myid
最後使用1.4的命令把三個zookeeper都啟動即可,啟動順序隨意沒要求。


四、報錯及處理


應用連線zookeepr報錯:Session 0x0 for server 192.168.220.128/192.168.220.128:2181,unexpected error,closing socket connection and attempting reconnect;

先看埠能否telnet通,如果通則使用./zkServer.sh status檢視zk是否確實已啟動,沒啟檢視bin/zookeeper.out中的報錯。

bin/zookeeper.out中報錯:“zookeeper address already in use”;顯然埠被佔用,要麼是其他程序佔用了配置的埠,要麼是上邊配置的clientPort和server中的埠有重複。

bin/zookeeper.out中報錯:Cannot open channel to 2 at election address /192.168.220.130:3888;這應該只是組成叢集的130節點未啟動,到130啟動起來zk即會正常。

Zookeeper安裝

zookeeper的安裝分為三種模式:單機模式、叢集模式和偽叢集模式。

單機模式

首先,從Apache官網下載一個Zookeeper穩定版本,本次教程採用的是zookeeper-3.4.9版本。

http://apache.fayea.com/zookeeper/zookeeper-3.4.9/
     然後解壓zookeeper-3.4.9.tar.gz檔案到安裝目錄下:

tar -zxvf zookeepre-3.4.9.tar.gz
 
  zookeeper要求Java執行環境,並且需要jdk版本1.6以上。為了以後的操作方便,可以對zookeeper的環境變數進行配置(該步驟可忽略)。方法如下,在/etc/profile檔案中加入以下內容:

#Set Zookeeper Environment

export ZOOKEEPER_HOME=/root/zookeeper-3.4.9
export PATH=$ZOOKEEPER_HOME/bin;$ZOOKEEPER_HOME/conf

Zookeeper伺服器包含在單個jar檔案中(本環境下為 zookeeper-3.4.9.jar),安裝此服務需要使用者自己建立一個配置檔案。

預設配置檔案路徑為 Zookeeper-3.4.9/conf/目錄下,檔名為zoo.cfg。進入conf/目錄下可以看到一個zoo_sample.cfg檔案,可供參考。通過以下程式碼在conf目錄下建立zoo.cfg檔案:

gedit zoo.cfg
 
在檔案中輸入以下內容並儲存

tickTime=2000
dataDir=/home/jxwch/hadoop/data/zookeeper
dataLogDir=/home/jxwch/hadoop/dataLog/zookeeper
clientPort=2181

  在這個檔案中,各個語句的含義:
    tickTime : 伺服器與客戶端之間互動的基本時間單元(ms)
    dataDir : 儲存zookeeper資料路徑
    dataLogDir : 儲存zookeeper日誌路徑,當此配置不存在時預設路徑與dataDir一致
    clientPort : 客戶端訪問zookeeper時經過伺服器端時的埠號

  使用單機模式時需要注意,在這種配置方式下,如果zookeeper伺服器出現故障,zookeeper服務將會停止。


叢集模式

    zookeeper最主要的應用場景是叢集,下面介紹如何在一個叢集上部署一個zookeeper。只要叢集上的大多數zookeeper服務啟動了,那麼總的zookeeper服務便是可用的。

另外,最好使用奇數臺伺服器。

如歌zookeeper擁有5臺伺服器,那麼在最多2臺伺服器出現故障後,整個服務還可以正常使用。

之後的操作和單機模式的安裝類似,我們同樣需要Java環境,下載最新版的zookeeper並配置相應的環境變數。不同之處在於每臺機器上的conf/zoo.cfg配置檔案的引數設定不同,使用者可以參考下面的配置:


tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/jxwch/server1/data
dataLogDir=/home/jxwch/server1/dataLog
clientPort=2181
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888
maxClientCnxns=60


    在這個配置檔案中,新出現的語句的含義:

      initLimit : 此配置表示允許follower連線並同步到leader的初始化時間,它以tickTime的倍數來表示。當超過設定倍數的tickTime時間,則連線失敗。

      syncLimit : Leader伺服器與follower伺服器之間資訊同步允許的最大時間間隔,如果超過此間隔,預設follower伺服器與leader伺服器之間斷開連結。

      maxClientCnxns : 限制連線到zookeeper伺服器客戶端的數量


      server.id=host:port:port : 表示了不同的zookeeper伺服器的自身標識,作為叢集的一部分,每一臺伺服器應該知道其他伺服器的資訊。使用者可以從“server.id=host:port:port” 中讀取到相關資訊。

在伺服器的data(dataDir引數所指定的目錄)下建立一個檔名為myid的檔案,這個檔案的內容只有一行,指定的是自身的id值。

比如,伺服器“1”應該在myid檔案中寫入“1”。這個id必須在叢集環境中伺服器標識中是唯一的,且大小在1~255之間。

這一樣配置中,zoo1代表第一臺伺服器的IP地址。

第一個埠號(port)是從follower連線到leader機器的埠,

第二個埠是用來進行leader選舉時所用的埠。

在叢集配置過程中有三個非常重要的埠:clientPort:2181、port:2888、port:3888。


偽叢集模式

偽叢集模式就是在單機環境下模擬叢集的Zookeeper服務。


在zookeeper叢集配置檔案中,clientPort引數用來設定客戶端連線zookeeper伺服器的埠。

server.1=IP1:2888:3888中,

IP1指的是組成Zookeeper伺服器的IP地址,

2888為組成zookeeper伺服器之間的通訊埠

3888為用來選舉leader的埠

由於偽叢集模式中,我們使用的是同一臺伺服器,也就是說,需要在單臺機器上執行多個zookeeper例項,所以我們必須要保證多個zookeeper例項的配置檔案的client埠不能衝突。


下面簡單介紹一下如何在單臺機器上建立偽叢集模式。首先將zookeeper-3.4.9.tar.gz分別解壓到server1,server2,server3目錄下:

tar -zxvf zookeeper-3.4.9.tar.gz  /home/jxwch/server1
 
tar -zxvf zookeeper-3.4.9.tar.gz /home/jxwch/server2
 
tar -zxvf zookeeper-3.4.9.tar.gz /home/jxwch/server3

然後在server1/data/目錄下建立檔案myid檔案並寫入“1”,

同樣在server2/data/,目錄下建立檔案myid並寫入“2”,server3進行同樣的操作。


下面分別展示在server1/conf/、server2/conf/、server3/conf/目錄下的zoo.cfg檔案:

server1/conf/zoo.cfg檔案

# Server 1
# The number of milliseconds of each tick
# 伺服器與客戶端之間互動的基本時間單元(ms)

tickTime=2000

# The number of ticks that the initial
# synchronization phase can take
# 此配置表示允許follower連線並同步到leader的初始化時間,它以tickTime的倍數來表示。當超過設定倍數的tickTime時間,則連線失敗。

initLimit=10

# The number of ticks that can pass between
# sending a request and getting an acknowledgement
# Leader伺服器與follower伺服器之間資訊同步允許的最大時間間隔,如果超過此間隔,預設follower伺服器與leader伺服器之間斷開連結

syncLimit=5

# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.

# 儲存zookeeper資料,日誌路徑
dataDir=/home/jxwch/server1/data
dataLogDir=/home/jxwch/server1/dataLog

# the port at which the clients will connect
# 客戶端與zookeeper相互互動的埠

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

#server.A=B:C:D  其中A是一個數字,代表這是第幾號伺服器;B是伺服器的IP地址;C表示伺服器與群集中的“領導者”交換資訊的埠;當領導者失效後,D表示用來執行選舉時伺服器相互通訊的埠。

# the maximum number of client connections.
# increase this if you need to handle more clients
# 限制連線到zookeeper伺服器客戶端的數量
maxClientCnxns=60

# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.

# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance

# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

server2/conf/zoo.cfg檔案

# Server 2
# The number of milliseconds of each tick
# 伺服器與客戶端之間互動的基本時間單元(ms)
tickTime=2000

# The number of ticks that the initial
# synchronization phase can take
# zookeeper所能接受的客戶端數量
initLimit=10

# The number of ticks that can pass between
# sending a request and getting an acknowledgement
# 伺服器與客戶端之間請求和應答的時間間隔
syncLimit=5

# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
# 儲存zookeeper資料,日誌路徑
dataDir=/home/jxwch/server2/data
dataLogDir=/home/jxwch/server2/dataLog


# the port at which the clients will connect
# 客戶端與zookeeper相互互動的埠
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


#server.A=B:C:D  其中A是一個數字,代表這是第幾號伺服器;B是伺服器的IP地址;C表示伺服器與群集中的“領導者”交換資訊的埠;當領導者失效後,D表示用來執行選舉時伺服器相互通訊的埠。

# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

server3/conf/zoo.cfg檔案


# Server 3
# The number of milliseconds of each tick
# 伺服器與客戶端之間互動的基本時間單元(ms)
tickTime=2000


# The number of ticks that the initial
# synchronization phase can take
# zookeeper所能接受的客戶端數量
initLimit=10

# The number of ticks that can pass between
# sending a request and getting an acknowledgement
# 伺服器與客戶端之間請求和應答的時間間隔
syncLimit=5

# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
# 儲存zookeeper資料,日誌路徑
dataDir=/home/jxwch/server3/data
dataLogDir=/home/jxwch/server3/dataLog


# the port at which the clients will connect
# 客戶端與zookeeper相互互動的埠
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


#server.A=B:C:D  其中A是一個數字,代表這是第幾號伺服器;B是伺服器的IP地址;C表示伺服器與群集中的“領導者”交換資訊的埠;當領導者失效後,D表示用來執行選舉時伺服器相互通訊的埠。

# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60

# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.

# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance

# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

從上述三個程式碼清單可以發現,除了clientPort不同之外,dataDir和dataLogDir也不同。另外,不要忘記dataDir所對應的目錄中建立的myid檔案來指定對應的zookeeper伺服器例項。

Zookeeper偽叢集模式執行

當上述偽叢集環境安裝成功後就可以測試是否安裝成功啦,我們可以嚐嚐鮮:

首先啟動server1伺服器:

cd server1/bin

bash zkServer.sh start

此時出現以下提示資訊,表示啟動成功:

開啟zookeeper.out檔案:

2017-02-23 16:17:46,419 [myid:] - INFO  [main:[email protected]] - Reading configuration from: /home/jxwch/server1/bin/../conf/zoo.cfg 2017-02-23 16:17:46,496 [myid:] - INFO  [main:[email protected]] - Resolved hostname: 127.0.0.1 to address: /127.0.0.1
2017-02-23 16:17:46,496 [myid:] - INFO  [main:[email protected]] - Resolved hostname: 127.0.0.1 to address: /127.0.0.1
2017-02-23 16:17:46,497 [myid:] - INFO  [main:[email protected]] - Resolved hostname: 127.0.0.1 to address: /127.0.0.1
2017-02-23 16:17:46,497 [myid:] - INFO  [main:[email protected]] - Defaulting to majority quorums 2017-02-23 16:17:46,511 [myid:1] - INFO  [main:[email protected]] - autopurge.snapRetainCount set to 3
2017-02-23 16:17:46,511 [myid:1] - INFO  [main:[email protected]] - autopurge.purgeInterval set to 0
2017-02-23 16:17:46,511 [myid:1] - INFO  [main:[email protected]] - Purge task is not scheduled. 2017-02-23 16:17:46,525 [myid:1] - INFO  [main:[email protected]] - Starting quorum peer 2017-02-23 16:17:46,631 [myid:1] - INFO  [main:[email protected]] - binding to port 0.0.0.0/0.0.0.0:2181
2017-02-23 16:17:46,664 [myid:1] - INFO  [main:[email protected]] - tickTime set to 2000
2017-02-23 16:17:46,664 [myid:1] - INFO  [main:[email protected]] - minSessionTimeout set to -1
2017-02-23 16:17:46,664 [myid:1] - INFO  [main:[email protected]] - maxSessionTimeout set to -1
2017-02-23 16:17:46,665 [myid:1] - INFO  [main:[email protected]] - initLimit set to 10
2017-02-23 16:17:46,771 [myid:1] - INFO  [main:[email protected]] - Reading snapshot /home/jxwch/server1/data/version-2/snapshot.400000015
2017-02-23 16:17:46,897 [myid:1] - INFO  [ListenerThread:[email protected]] - My election bind port: /127.0.0.1:3888
2017-02-23 16:17:46,913 [myid:1] - INFO  [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:[email protected]] - LOOKING 2017-02-23 16:17:46,915 [myid:1] - INFO  [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:[email protected]] - New election. My id =  1, proposed zxid=0x500000026
2017-02-23 16:17:46,922 [myid:1] - INFO  [WorkerReceiver[myid=1]:[email protected]] - Notification: 1 (message format version), 1 (n.leader), 0x500000026 (n.zxid), 0x1 (n.round), LOOKING (n.state), 1 (n.sid), 0x5 (n.peerEpoch) LOOKING (my state) 2017-02-23 16:17:46,940 [myid:1] - WARN  [WorkerSender[myid=1]:[email protected]] - Cannot open channel to 2 at election address /127.0.0.1:3889 java.net.ConnectException: 拒絕連線 at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:579)
    at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:381)
    at org.apache.zookeeper.server.quorum.QuorumCnxManager.toSend(QuorumCnxManager.java:354)
    at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.process(FastLeaderElection.java:452)
    at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.run(FastLeaderElection.java:433)
    at java.lang.Thread.run(Thread.java:745) 2017-02-23 16:17:46,943 [myid:1] - INFO  [WorkerSender[myid=1]:[email protected]] - Resolved hostname: 127.0.0.1 to address: /127.0.0.1 2017-02-23 16:17:46,944 [myid:1] - WARN  [WorkerSender[myid=1]:[email protected]] - Cannot open channel to 3 at election address /127.0.0.1:3890 java.net.ConnectException: 拒絕連線 at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:579)
    at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:381)
    at org.apache.zookeeper.server.quorum.QuorumCnxManager.toSend(QuorumCnxManager.java:354)
    at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.process(FastLeaderElection.java:452)
    at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.run(FastLeaderElection.java:433)
    at java.lang.Thread.run(Thread.java:745) 2017-02-23 16:17:46,944 [myid:1] - INFO  [WorkerSender[myid=1]:[email protected]] - Resolved hostname: 127.0.0.1 to address: /127.0.0.1

產生上述兩條Waring資訊是因為zookeeper服務的每個例項都擁有全域性的配置資訊,他們在啟動的時候需要隨時隨地的進行leader選舉,此時server1就需要和其他兩個zookeeper例項進行通訊,但是,另外兩個zookeeper例項還沒有啟動起來,因此將會產生上述所示的提示資訊。當我們用同樣的方式啟動server2和server3後就不會再有這樣的警告資訊了。

當三臺伺服器均成功啟動後切換至server1/bin/目錄下執行以下命令:

bash zkServer.sh status
    終端出現以下提示資訊:  

說明server1伺服器此時處於follower模式
同樣切換至server2/bin目錄下執行相同的命令,返回如下結果:
說明server2被選舉為leader。