ZooKeeper 安裝模式
- 單機模式:ZooKeeper 運行在一臺服務器上,適合測試環境;
- 僞集羣模式:在一臺物理機上運行多個 ZooKeeper 實例;
- 集羣模式:ZooKeeper 運行在一個集羣上,稱爲 ensemble,適合生產環境;
ZooKeeper 經過複製來實現高可用性,只要集合中半數以上的機器處於可用狀態就能夠保證服務繼續。由於 ZooKeeper 的複製策略是保證 znode 樹的每個修改都會被複制到集羣中超過半數的機器上。
準備工做
Windows 下的配置
單機模式(適合開發環境)
一、將下載的壓縮包 zookeeper-3.4.11.tar.gz 解壓到 C:\solrCloud\zk_server_single(如下簡稱 %ZK_HOME%
) 目錄下;
二、將 %ZK_HOME%/conf/zoo_sample.cfg 另存爲
zoo.cfg
,並修改該配置文件:
# ----------------------------------------------------------------------
# 基本配置(最低配置)
# ----------------------------------------------------------------------
# the port at which the clients will connect
# 監聽客戶端鏈接的端口
clientPort=2181
# The number of milliseconds of each tick
# 服務器之間或者客戶端與服務器之間維持心跳的時間間隔,
# 會話(session)的過時時間爲2倍的 tickTime;
tickTime=2000
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
# 存儲內存數據庫快照的位置,除非另外說明,不然就是指數據庫的更新事務日誌
dataDir=../data
三、而後啓動 %ZK_HOME%/bin/zkServer.cmd 便可;
四、由於這裏是單機模式,ZooKeeper 沒有其餘機器能夠複製更新事務,因此當 ZooKeeper 處理失敗時服務就會掛掉,這樣的適合做爲開發環境。
五、鏈接 ZooKeeper 服務器,能夠經過 %ZK_HOME%/bin/zkCli.cmd 做爲客戶端鏈接到 ZooKeeper 服務器。
bin\zkCli.cmd -server 127.0.0.1:181
出現 Welcome to ZooKeeper!和 JLine support is enabled,則表示已經鏈接成功!
此時也能夠經過 netstat 命令查看 2181 端口是否被佔用,或者經過 jps 命令查看啓動的 JAVA 進程狀況來檢查 ZooKeeper 是否啓動正常!
六、輸入
help 命令能夠查看 ZooKeeper 的一些命令:
[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
下面看一下 ZooKeeper 命令的一些示例:
[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) 3] ls /
[zookeeper, zk_test]
[zk: 127.0.0.1:2181(CONNECTED) 4] get /zk_test
my_data
cZxid = 0x2a
ctime = Wed Apr 11 10:49:31 CST 2018
mZxid = 0x2a
mtime = Wed Apr 11 10:49:31 CST 2018
pZxid = 0x2a
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0
[zk: 127.0.0.1:2181(CONNECTED) 5] set /zk_test junk
cZxid = 0x2a
ctime = Wed Apr 11 10:49:31 CST 2018
mZxid = 0x2b
mtime = Wed Apr 11 10:50:33 CST 2018
pZxid = 0x2a
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
[zk: 127.0.0.1:2181(CONNECTED) 6] delete /zk_test
[zk: 127.0.0.1:2181(CONNECTED) 7] ls /
[zookeeper]
命令 |
描述 |
conf |
打印服務配置的詳細信息 |
cons |
列舉全部鏈接到該服務器的客戶端的鏈接或會話,包括髮送/接收的包數量,會話 id,操做延遲,最後執行的操做等 |
crst |
重置全部鏈接或會話的統計信息 |
dump |
列舉未經處理的會話和臨時節點,只對 leader 有效。 |
envi |
打印服務環境的詳細信息 |
ruok |
測試服務器是否處於正確狀態,若是是返回"imok",不然不做任何響應。返回"imok"只是表示服務器進程是活動的,且綁定到指定的客戶端端口,並不表明該服務器已經加入到集羣中。 |
srst |
重置服務器統計信息。 |
srvr |
列舉服務器的全部詳細信息。 |
stat |
列舉服務器及其鏈接的客戶端的簡要信息。 |
wchs |
列舉服務器上 watch 的簡要信息。 |
wchc |
經過 session 列舉服務器上 watch 的詳細信息。輸出一個與 watch 相關的會話(鏈接)列表。 |
wchp |
經過路徑列舉服務器上 watch 的詳細信息。輸出一個與 watch 相關的路徑(znode)列表。 |
mntr |
輸出一些用於監測集羣健康的變量。 |
須要下載 netcat for windows,並在環境變量 path 中添加 nc.exe 所在目錄。
C:\solrCloud\zk_server_fake\bin>echo mntr | nc localhost 2181
zk_version 3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT
zk_avg_latency 0
zk_max_latency 0
zk_min_latency 0
zk_packets_received 7
zk_packets_sent 6
zk_num_alive_connections 1
zk_outstanding_requests 0
zk_server_state follower
zk_znode_count 4
zk_watch_count 0
zk_ephemerals_count 0
zk_approximate_data_size 27
C:\solrCloud\zk_server_fake\bin>echo ruok | nc localhost 2181
imok
僞集羣模式
一、將上面配置好的 C:\solrCloud\zk_server_single 文件夾另存爲一份 C:\solrCloud\zk_server_fake(簡稱%ZK_HOME%)
2
、僞集羣模式是經過每一個配置文檔模擬一臺服務器,因此將 %ZK_HOME%\conf\zoo.cfg 文件複製出三份 zoo1.cfg、zoo2.cfg 和 zoo3.cfg 配置文件,配置信息以下:
zoo1.cfg
# ----------------------------------------------------------------------
# 基本配置(最低配置)
# ----------------------------------------------------------------------
# the port at which the clients will connect
# 監聽客戶端鏈接的端口
clientPort=2181
# The number of milliseconds of each tick
# 服務器之間或者客戶端與服務器之間維持心跳的時間間隔,
# 會話(session)的過時時間爲2倍的 tickTime;
tickTime=2000
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
# 存儲內存數據庫快照的位置,除非另外說明,不然就是指數據庫的更新事務日誌
dataDir=../data1
# ----------------------------------------------------------------------
# 高級配置
# ----------------------------------------------------------------------
# 存儲事務日誌的位置,分離出默認的 dataDir 設置中包含的更新事務日誌記錄,避免日誌和快照之間的競爭
dataLogDir=../log1
# Java 屬性:zookeeper.globalOutstandingLimit
# 客戶端提交請求的速度要比 ZooKeeper 處理請求的速度快不少,尤爲有大量的客戶端的時候。
# 爲了不因爲大量請求致使 ZooKeeper 內存耗盡,ZooKeeper 將調節客戶端以保證系統中只有不足 globalOutstandingLimit 個未處理請求。
# 默認值 1000
# globalOutstandingLimit=1000
# Java 屬性:zookeeper.preAllocSize
# 爲了不地址尋址,ZooKeeper 給事務日誌文件分配了 preAllocSize 字節大小的空間。默認塊大小爲 64M。
# 若是常用快照則能夠修改該值,減少塊大小。
# preAllocSize
# Java 屬性:zookeeper.snapCount
# ZooKeeper 使用快照和一個快照日誌文件來記錄它的事務。snapCount 決定了快照時在事務日誌中能夠記錄的事務數量。
# 爲了不集羣中全部的機器同時拍攝快照,每一個 ZooKeeper 服務器只有在事務日誌中的事務數量達到一個值時才拍攝快照,
# 該值時在運行時生成的介於[snapCount/2+1, snapCount]範圍內的隨機數。默認值 100000
# snapCount=100000
# the maximum number of client connections.
# increase this if you need to handle more clients
# 限制 ZooKeeper 集羣中一個客戶端的併發鏈接數量,經過 IP 地址進行判斷識別。
# 能夠用於阻止某些 DoS 攻擊,包括 file descriptor exhaustion。默認值 60。
# 設置爲0時表示取消併發數量限制。
# maxClientCnxns=60
# 3.3.0新增設置
# 最小會話超時時間,默認 minSession=2*tickTime
# minSessionTimeout
# 最大會話超時時間,默認 maxSession=20*tickTime
# maxSessionTimeout
# 3.4.0新增設置
# 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
# ----------------------------------------------------------------------
# 集羣配置
# ----------------------------------------------------------------------
# The number of ticks that the initial
# synchronization phase can take
# 容許 follower 鏈接並同步到 leader 的初始化鏈接次數,以 tickTime 爲單位,總計時長爲 initLimit*tickTime 毫秒
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
# leader 與 follower 之間發送消息時,請求和應答之間的通訊次數,以 tickTime 爲單位,總計時長爲 syncLimit*tickTime 毫秒
syncLimit=5
# A:一個正整數,表示服務器的編號
# B:服務器的 IP 地址
# C:ZooKeeper 服務器之間的通訊端口
# D:leader 選舉端口
# server.A=B:C:D
server.1=localhost:2287:3387
server.2=localhost:2288:3388
server.3=localhost:2289:3389
zoo2.cfg,除了以下配置不一樣,其餘與 zoo1.cfg 一致
clientPort=2182
dataDir=../data2
dataLogDir=../log2
zoo3.cfg,除了以下配置不一樣,其餘與 zoo1.cfg 一致
clientPort=2183
dataDir=../data3
dataLogDir=../log3
要注意其中的 clientPort 端口、dataDir 和 dataLogDir 目錄設置,不一樣的 ZooKeeper 服務器對應不一樣的配置項。
此時須要手動建立 data一、data2 和 data3,log一、log2 和 log3 六個文件夾。
三、須要在每一個 data 目錄下一個 myid 文件裏面分別寫入 1,2,3,對應 server.x 中的 x 數字,表示不一樣 ZooKeeper 服務器的編號。
四、而後將 %ZK_HOME%/bin/zkServer.cmd 複製三份 zkServer1.cmd、zkServer2.cmd 和 zkServer3.cmd 來模擬三臺 ZooKeeper 服務器啓動,須要在文件中增長對應配置文件的參數設置。set ZOOCFG=..\conf\zooX.cfg
,其中 X 表示對應服務器的 zoo.cfg 配置文件,與 2 中的相對應。最終結果以下圖所示:
五、最後啓動三個 ZooKeeper 服務器;
首先啓動 zkServer1.cmd
C:\solrCloud\zk_server_fake\bin>zkServer1.cmd
C:\solrCloud\zk_server_fake\bin>call "C:\Program Files\Java\jdk1.8.0_162"\bin\java "-Dzookeeper.log.dir=C:\solrCloud\zk_server_fake\bin\.." "-Dzookeeper.root.logger=INFO,CONSOLE" -cp "C:\solrCloud\zk_server_fake\bin\..\build\classes;C:\solrCloud\zk_server_fake\bin\..\build\lib\*;C:\solrCloud\zk_server_fake\bin\..\*;C:\solrCloud\zk_server_fake\bin\..\lib\*;C:\solrCloud\zk_server_fake\bin\..\conf" org.apache.zookeeper.server.quorum.QuorumPeerMain "..\conf\zoo1.cfg"
2018-04-11 11:46:40,470 [myid:] - INFO [main:QuorumPeerConfig@136] - Reading configuration from: ..\conf\zoo1.cfg
2018-04-11 11:46:40,489 [myid:] - INFO [main:QuorumPeer$QuorumServer@184] - Resolved hostname: localhost to address: localhost/127.0.0.1
2018-04-11 11:46:40,489 [myid:] - INFO [main:QuorumPeer$QuorumServer@184] - Resolved hostname: localhost to address: localhost/127.0.0.1
2018-04-11 11:46:40,491 [myid:] - INFO [main:QuorumPeer$QuorumServer@184] - Resolved hostname: localhost to address: localhost/127.0.0.1
2018-04-11 11:46:40,491 [myid:] - INFO [main:QuorumPeerConfig@398] - Defaulting to majority quorums
2018-04-11 11:46:40,503 [myid:1] - INFO [main:DatadirCleanupManager@78] - autopurge.snapRetainCount set to 3
2018-04-11 11:46:40,503 [myid:1] - INFO [main:DatadirCleanupManager@79] - autopurge.purgeInterval set to 0
2018-04-11 11:46:40,503 [myid:1] - INFO [main:DatadirCleanupManager@101] - Purge task is not scheduled.
2018-04-11 11:46:40,560 [myid:1] - INFO [main:QuorumPeerMain@130] - Starting quorum peer
2018-04-11 11:46:40,746 [myid:1] - INFO [main:ServerCnxnFactory@117] - Using org.apache.zookeeper.server.NIOServerCnxnFactory as server connection factory
2018-04-11 11:46:40,747 [myid:1] - INFO [main:NIOServerCnxnFactory@89] - binding to port 0.0.0.0/0.0.0.0:2181
2018-04-11 11:46:40,753 [myid:1] - INFO [main:QuorumPeer@1158] - tickTime set to 2000
2018-04-11 11:46:40,753 [myid:1] - INFO [main:QuorumPeer@1204] - initLimit set to 10
2018-04-11 11:46:40,753 [myid:1] - INFO [main:QuorumPeer@1178] - minSessionTimeout set to -1
2018-04-11 11:46:40,753 [myid:1] - INFO [main:QuorumPeer@1189] - maxSessionTimeout set to -1
2018-04-11 11:46:40,760 [myid:1] - INFO [main:QuorumPeer@1467] - QuorumPeer communication is not secured!
2018-04-11 11:46:40,761 [myid:1] - INFO [main:QuorumPeer@1496] - quorum.cnxn.threads.size set to 20
2018-04-11 11:46:40,764 [myid:1] - INFO [main:QuorumPeer@668] - currentEpoch not found! Creating with a reasonable default of 0. This should only happen when you are upgrading your installation
2018-04-11 11:46:40,771 [myid:1] - INFO [main:QuorumPeer@683] - acceptedEpoch not found! Creating with a reasonable default of 0. This should only happen when you are upgrading your installation
2018-04-11 11:46:40,781 [myid:1] - INFO [ListenerThread:QuorumCnxManager$Listener@736] - My election bind port: localhost/127.0.0.1:3387
2018-04-11 11:46:40,789 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumPeer@909] - LOOKING
2018-04-11 11:46:40,790 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:FastLeaderElection@820] - New election. My id = 1, proposed zxid=0x0
2018-04-11 11:46:40,792 [myid:1] - INFO [WorkerReceiver[myid=1]:FastLeaderElection@602] - Notification: 1 (message format version), 1 (n.leader), 0x0 (n.zxid), 0x1 (n.round), LOOKING (n.state), 1 (n.sid), 0x0 (n.peerEpoch) LOOKING (my state)
此時會提示說沒法打開"
2號"通道和"3號"通道,錯誤提示以下,由於"2號"服務器和"3號
"服務器還未啓動。
2018-04-11 11:48:16,324 [myid:1] - WARN [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumCnxManager@584] - Cannot open channel to 2 at election address localhost/127.0.0.1:3388
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:558)
at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectAll(QuorumCnxManager.java:610)
at org.apache.zookeeper.server.quorum.FastLeaderElection.lookForLeader(FastLeaderElection.java:845)
at org.apache.zookeeper.server.quorum.QuorumPeer.run(QuorumPeer.java:957)
2018-04-11 11:48:32,332 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumPeer$QuorumServer@184] - Resolved hostname: localhost to address: localhost/127.0.0.1
2018-04-11 11:48:33,338 [myid:1] - WARN [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumCnxManager@584] - Cannot open channel to 3 at election address localhost/127.0.0.1:3389
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:558)
at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectAll(QuorumCnxManager.java:610)
at org.apache.zookeeper.server.quorum.FastLeaderElection.lookForLeader(FastLeaderElection.java:845)
at org.apache.zookeeper.server.quorum.QuorumPeer.run(QuorumPeer.java:957)
2018-04-11 11:48:33,338 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumPeer$QuorumServer@184] - Resolved hostname: localhost to address: localhost/127.0.0.1
2018-04-11 11:48:33,340 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:FastLeaderElection@854] - Notification time out: 51200
一樣再啓動 zkServer2.cmd,此時 zkServ1 中仍然會提示沒法鏈接上"
3號"通道,可是有提示說鏈接上"2號
"通道,提示以下:
而 zkServer2.cmd 則提示沒法鏈接"3號"通道,而後與鏈接上的"1號"服務器開始競選 leader,產生一個 leader 和 一個 follow。
最後再啓動 zkServer3.cmd,此時再也不提示異常了,而且會在三臺服務器之間再一次競選一個 leader,剩下兩個爲 follow。
不過在 Windows 系統下沒法經過 zkServer.cmd 查看服務器狀態,須要安裝 Cygwin 工具,而後執行以下命令查看三個服務器的狀態:
集羣模式
與僞集羣配置同樣,只要將不一樣配置文件(zoo.cfg)分別部署在不一樣服務器上便可。
參考說明
by. Memento