Zookeeper安裝和部署:ZooKeeper是一個分布式的,開放源碼的分布式應用程序協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個為分布式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分布式同步、組服務等。
ZooKeeper的目標就是封裝好復雜易出錯的關鍵服務,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。
ZooKeeper包含一個簡單的原語集, 提供Java和C的接口。
ZooKeeper代碼版本中,提供了分布式獨享鎖、選舉、隊列的接口,代碼在zookeeper-3.4.8\src\recipes。其中分布鎖和隊列有Java和C兩個版本,選舉只有Java版本。
2. Zookeeper原理
ZooKeeper是以Fast Paxos算法為基礎的,Paxos 算法存在活鎖的問題,即當有多個proposer交錯提交時,有可能互相排斥導致沒有一個proposer能提交成功,而Fast Paxos作了一些優化,通過選舉產生一個leader (領導者),只有leader才能提交proposer,具體算法可見Fast Paxos。因此,要想弄懂ZooKeeper首先得對Fast Paxos有所了解。
ZooKeeper的基本運轉流程:
1、選舉Leader。
2、同步數據。
3、選舉Leader過程中算法有很多,但要達到的選舉標准是一致的。
4、Leader要具有最高的zxid。
5、集群中大多數的機器得到響應並follow選出的Leader。[3]
3. Zookeeper特點
在Zookeeper中,znode是一個跟Unix文件系統路徑相似的節點,可以往這個節點存儲或獲取數據。如果在創建znode時Flag設置為EPHEMERAL,那么當創建這個znode的節點和Zookeeper失去連接后,這個znode將不再存在在Zookeeper里,Zookeeper使用Watcher察覺事件信息。當客戶端接收到事件信息,比如連接超時、節點數據改變、子節點改變,可以調用相應的行為來處理數據。Zookeeper的Wiki頁面展示了如何使用Zookeeper來處理事件通知,隊列,優先隊列,鎖,共享鎖,可撤銷的共享鎖,兩階段提交。
那么Zookeeper能做什么事情呢,簡單的例子:假設我們有20個搜索引擎的服務器(每個負責總索引中的一部分的搜索任務)和一個總服務器(負責向這20個搜索引擎的服務器發出搜索請求並合並結果集),一個備用的總服務器(負責當總服務器宕機時替換總服務器),一個web的cgi(向總服務器發出搜索請求)。搜索引擎的服務器中的15個服務器提供搜索服務,5個服務器正在生成索引。這20個搜索引擎的服務器經常要讓正在提供搜索服務的服務器停止提供服務開始生成索引,或生成索引的服務器已經把索引生成完成可以提供搜索服務了。使用Zookeeper可以保證總服務器自動感知有多少提供搜索引擎的服務器並向這些服務器發出搜索請求,當總服務器宕機時自動啟用備用的總服務器。
4. Zookeeper的下載
可以從 https://zookeeper.apache.org/releases.html 下載ZooKeeper,目前最新的穩定版本為 3.4.8 版本,用戶可以自行選擇一個速度較快的鏡像來下載即可。
5. Zookeeper的目錄結構
下載並解壓ZooKeeper軟件壓縮包后,可以看到zk包含以下的文件和目錄:
ZooKeeper軟件的文件和目錄
bin目錄
zk的可執行腳本目錄,包括zk服務進程,zk客戶端,等腳本。其中,.sh是Linux環境下的腳本,.cmd是Windows環境下的腳本。 lib目錄
zk依賴的包。 libexec目錄
一些用於操作zk的工具包。
5.單機模式
ZooKeeper的安裝包括單機模式安裝,以及集群模式安裝。
單機模式較簡單,是指只部署一個zk進程,客戶端直接與該zk進程進行通信。
在開發測試環境下,通過來說沒有較多的物理資源,因此我們常使用單機模式。當然在單台物理機上也可以部署集群模式,但這會增加單台物理機的資源消耗。故在開發環境中,我們一般使用單機模式。
5.1 運行配置
在etc/zookeeper/目錄下提供了zoo.cfg,打開zoo.cfg,可以看到默認的一些配置。
tickTime
時長單位為毫秒,為zk使用的基本時間度量單位。例如,1 * tickTime是客戶端與zk服務端的心跳時間,2 * tickTime是客戶端會話的超時時間。
tickTime的默認值為2000毫秒,更低的tickTime值可以更快地發現超時問題,但也會導致更高的網絡流量(心跳消息)和更高的CPU使用率(會話的跟蹤處理)。
1
|
tickTime=
2000
|
clientPort
zk服務進程監聽的TCP端口,默認情況下,服務端會監聽2181端口。
1
|
clientPort=
2181
|
dataDir
無默認配置,必須配置,用於配置存儲快照文件的目錄。如果沒有配置dataLogDir,那么事務日志也會存儲在此目錄。
1
2
|
dataDir=/usr/local/var/run/zookeeper/data
dataLogDir=/usr/local/var/run/zookeeper/logs
|
5.2 啟動
在mac環境下,將zookeeper的bin目錄配置到環境變量中,直接執行命令
1
|
zkServer start
|
這個命令使得zk服務進程在后台進行。
如果想在前台中運行以便查看服務器進程的輸出日志,可以通過以下命令運行:
1
|
zkServer start-foreground
|
執行此命令,可以看到大量詳細信息的輸出,以便允許查看服務器發生了什么。
5.3 連接
如果是連接同一台主機上的zk進程,那么直接運行bin/目錄下的zkCli.cmd(Windows環境下)或者zkCli.sh(mac環境下),即可連接上zk。
直接執行zkCli.cmd或者zkCli.sh命令默認以主機號 127.0.0.1,端口號 2181 來連接zk,如果要連接不同機器上的zk,可以使用 -server 參數,例如:
1
|
zkCli -server
192.168
.
0.1
:
2181
|
6.集群模式
單機模式的zk進程雖然便於開發與測試,但並不適合在生產環境使用。在生產環境下,我們需要使用集群模式來對zk進行部署。
注意
在集群模式下,建議至少部署3個zk進程,或者部署奇數個zk進程。如果只部署2個zk進程,當其中一個zk進程掛掉后,剩下的一個進程並不能構成一個quorum的大多數。因此,部署2個進程甚至比單機模式更不可靠,因為2個進程其中一個不可用的可能性比一個進程不可用的可能性還大。
6. 1 運行配置
在集群模式下,所有的zk進程可以使用相同的配置文件(是指各個zk進程部署在不同的機器上面),例如如下配置:
1
2
3
4
5
6
7
|
tickTime=
2000
dataDir=/home/lidong/zookeeper
clientPort=
2181
initLimit=
5
syncLimit=
2
server.
1
=
192.168
.
0.105
:
2888
:
3888
server.
2
=
192.168
.
0.108
:
2888
:
3888
|
initLimit
ZooKeeper集群模式下包含多個zk進程,其中一個進程為leader,余下的進程為follower。
當follower最初與leader建立連接時,它們之間會傳輸相當多的數據,尤其是follower的數據落后leader很多。initLimit配置follower與leader之間建立連接后進行同步的最長時間。
syncLimit
配置follower和leader之間發送消息,請求和應答的最大時間長度。
tickTime
tickTime則是上述兩個超時配置的基本單位,例如對於initLimit,其配置值為5,說明其超時時間為 2000ms * 5 = 10秒。
server.id=host:port1:port2
其中id為一個數字,表示zk進程的id,這個id也是dataDir目錄下myid文件的內容。
host是該zk進程所在的IP地址,port1表示follower和leader交換消息所使用的端口,port2表示選舉leader所使用的端口。
dataDir
其配置的含義跟單機模式下的含義類似,不同的是集群模式下還有一個myid文件。myid文件的內容只有一行,且內容只能為1 - 255之間的數字,這個數字亦即上面介紹server.id中的id,表示zk進程的id。
注意
如果僅為了測試部署集群模式而在同一台機器上部署zk進程,server.id=host:port1:port2配置中的port參數必須不同。但是,為了減少機器宕機的風險,強烈建議在部署集群模式時,將zk進程部署不同的物理機器上面。
6. 2啟動
假如我們打算在兩台不同的機器 192.168.0.105(windows),192.168.0.108(mac os)上各部署一個zk進程,以構成一個zk集群。
兩個zk進程均使用相同的 zoo.cfg 配置:
192.168.0.105(windows)
tickTime=2000
dataDir=D:/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=192.168.0.105:2888:3888
server.2=192.168.0.108:2888:3888
192.168.0.100(mac os)
tickTime=2000
dataDir=/home/lidong/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=192.168.0.105:2888:3888
server.2=192.168.0.108:2888:3888
在window主機器dataDir目錄( D:/zookeeper目錄)下,分別生成一個myid文件,其內容分別為1,2。
在Mac os主機器dataDir目錄( /home/lidong/zookeeper)下,分別生成一個myid文件,其內容分別為1,2。
然后分別在這兩台機器上啟動zk進程,這樣我們便將zk集群啟動了起來。
6. 3連接
可以使用以下命令來連接一個zk集群:
1
|
zkCli -server
192.168
.
0.105
:
2181
,
192.168
.
0.108
:
2181
|
成功連接后,可以看到如下輸出:
1
2
3
4
5
6
7
8
|
Connecting to
192.168
.
0.105
:
2181
,
192.168
.
0.108
:
2181
Welcome to ZooKeeper!
JLine support is enabled
WATCHER::
WatchedEvent state:SyncConnected type:None path:
null
[zk:
192.168
.
0.105
:
2181
,
192.168
.
0.108
:
2181
(CONNECTED)
0
]
|
從日志輸出可以看到,客戶端連接的是192.168.0.108:2181進程,客戶端已成功連接上zk集群。
注意:連接到那個集群是隨機的。