ZooKeeper管理員指南——部署與管理ZooKeeper

五柳-先生發表於2015-07-20

本文以ZooKeeper3.4.3版本的官方指南為基礎:http://zookeeper.apache.org/doc/r3.4.3/zookeeperAdmin.html,補充一些作者運維實踐中的要點,圍繞ZK的部署和運維兩個方面講一些管理員需要知道的東西。本文並非一個ZK搭建的快速入門,關於這方面,可以檢視《ZooKeeper快速搭建》。

1.部署

本章節主要講述如何部署ZooKeeper,包括以下三部分的內容:

  • 系統環境
  • 叢集模式的配置
  • 單機模式的配置

系統環境和叢集模式配置這兩節內容大體講述瞭如何部署一個能夠用於生產環境的ZK叢集。如果僅僅是想在單機上將ZK執行起來,進行一些開發與測試,那麼第三部分或許是你的菜。

1.1系統環境

1.1.1平臺支援

平 臺

執行client

執行server

開發環境

生產環境

GNU/Linux

Sun Solaris

FreeBSD

ⅹ,對nio的支援不好

Win32

MacOSX

:執行client是指作為客戶端,與server進行資料通訊,而執行server是指將ZK作為伺服器部署執行。

1.1.2軟體環境

ZooKeeper Server是一個Java語言實現的分散式協調服務框架,因此需要6或更高版本的JDK支援。叢集的機器數量方面,寬泛的講,其實是任意臺機器都可以部署執行的,注意,這裡並沒有說一定要奇數臺機器哦!通常情況下,建議使用3臺獨立的Linux伺服器構成的一個ZK叢集。

1.2叢集模式的配置

為了確保ZooKeeper服務的穩定與可靠性,通常是搭建成一個ZK叢集來對外提供服務。關於ZooKeeper,需要明確一個很重要的特性:叢集中只要有過半的機器是正常工作的,那麼整個叢集對外就是可用的(本文下面就用“過半存活即可用”來代替這個特性吧^-^)。正是基於這個特性,建議是將ZK叢集的機器數量控制為奇數較為合適。為什麼選擇奇數臺機器,我們可以來看一下,假如是4臺機器構成的ZK叢集,那麼只能夠允許叢集中有一個機器down掉,因為如果down掉2臺,那麼只剩下2臺機器,顯然沒有過半。而如果是5臺機器的叢集,那麼就能夠對2臺機器down掉的情況進行容災了。

你可以按照以下步驟來配置一個ZK機器,更多詳細步驟請檢視《ZooKeeper快速搭建》:

1. 安裝JDK。相關連結:http://java.sun.com/javase/downloads/index.jsp

2. 設定Java heap 大小。避免記憶體與磁碟空間的交換,能夠大大提升ZK的效能,設定合理的heap大小則能有效避免此類空間交換的觸發。在正式釋出上線之前,建議是針對使用場景進行一些壓力測試,確保正常執行後記憶體的使用不會觸發此類交換。通常在一個實體記憶體為4G的機器上,最多設定-Xmx為3G。

3. 下載安裝ZooKeeper,相關連結:http://zookeeper.apache.org/releases.html

4. 配置檔案zoo.cfg。初次使用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

本文後續章節會對這些引數進行詳細的介紹,這裡只是簡單說幾點:叢集中的每臺機器都需要感知整個叢集是由哪幾臺機器組成的,在配置檔案中,可以按照這樣的格式,每行寫一個機器配置:server.id=host:port:port. 關於這個id,我們稱之為Server ID,用來標識該host在叢集中的機器序號。在每個ZooKeeper機器上,我們都需要在資料目錄(資料目錄就是dataDir引數指定的那個目錄)下建立一個myid檔案,該檔案只有一行內容,並且是一個數字——對應這個Server ID數字。

在ZooKeeper的設計中,叢集中所有機器上的zoo.cfg檔案的內容都是一致的。因此最好是用SVN把這個檔案管理起來,保證每個機器都能共享到一份相同的配置。

5. 關於myid檔案。myid檔案中只有一個數字,即一個Server ID。例如,server.1 的myid檔案內容就是“1”。注意,請確保每個server的myid檔案中id數字不同,並且和server.id=host:port:port中的id一致。另外,id的範圍是1~255。

6. 至此,配置檔案基本ok,可以嘗試使用如下命令來啟動zookeeper了:

$ java -cp zookeeper-3.4.3.jar:lib/slf4j-api-1.6.1.jar:lib/slf4j-log4j12-1.6.1.jar:lib/log4j-1.2.15.jar:conf org.apache.zookeeper.server.quorum.QuorumPeerMain conf/zoo.cfg

注意,不同的ZK版本,依賴的log4j和slf4j版本也是不一樣的,請看清楚自己的版本後,再執行上面這個命令。QuorumPeerMain類會啟動ZooKeeper Server,同時,JMX MB也會被啟動,方便管理員在JMX管理控制檯上進行ZK的控制。這裡有對ZK JMX的詳細介紹:http://zookeeper.apache.org/doc/r3.4.3/zookeeperJMX.html.  另外,完全可以有更簡便的方式,直接使用%ZK_HOME%/bin 中的指令碼啟動即可。

./zkServer.sh start

7. 連線ZK host來檢驗部署是否成功。
->Java語言的話,可以通過執行這個命令來檢測:

$ java -cp zookeeper-3.4.3.jar:lib/slf4j-api-1.6.1.jar:lib/slf4j-log4j12-1.6.1.jar:lib/log4j-1.2.15.jar:conf:src/java/lib/jline-0.9.94.jar org.apache.zookeeper.ZooKeeperMain -server 127.0.0.1:2181

->如果是C語言的話,方法如下:

$ make cli_st
$ make cli_mt

然後按照的這樣的方式連線ZK:$ cli_mt 127.0.0.1:2181。無論執行哪種客戶端,最終都是一個類似於檔案系統的命令列操作。

注意:除了上面這種檢測方法,其實%ZK_HOME%/bin也有其它指令碼,下面這個命令執行後,就進入了zookeeper樹狀結構的檔案系統中。

./zkCli.sh

另外,還有一種方式,能夠檢視ZK伺服器當前狀態,如下,這個能夠很好的看出目前這個機器的執行情況了:

$ echo stat|nc localhost 2181
Zookeeper version: 3.4.3-1240972, built on 02/06/2012 10:48 GMT
Clients:
/127.0.0.1:40293[0](queued=0,recved=1,sent=0)

Latency min/avg/max: 1/2/3
Received: 4
Sent: 3
Outstanding: 0
Zxid: 0x200000006
Mode: leader
Node count: 4

1.3單機模式的配置

如果你想安裝一個ZooKeeper來進行開發測試,通常可以使用單機模式來啟動ZK。大體的步驟和上面說的是一樣了,除了配置檔案會更加簡單一些。詳細的配置方法可以檢視這裡:http://zookeeper.apache.org/doc/r3.4.3/zookeeperStarted.html#sc_InstallingSingleMode

2.運 維

本章節主要要講述如何更好地運維ZooKeepr,大致包含以下幾部分內容:

  • 部署方案的設計
  • 日常運維
  • Server的自檢恢復
  • 監控
  • 日誌管理
  • 資料載入出錯
  • 配置引數詳解
  • 常用的四字命令
  • 資料檔案管理
  • 注意事項

2.1部署方案的設計

我們常說的ZooKeeper能夠提供高可用分散式協調服務,是要基於以下兩個條件:

  1. 叢集中只有少部分的機器不可用。這裡說的不可用是指這些機器或者是本身down掉了,或者是因為網路原因,有一部分機器無法和叢集中其它絕大部分的機器通訊。例如,如果ZK叢集是跨機房部署的,那麼有可能一些機器所在的機房被隔離了。
  2. 正確部署ZK server,有足夠的磁碟儲存空間以及良好的網路通訊環境。

下面將會從叢集和單機兩個維度來說明,幫助zookeeper管理員儘可能地提高ZK叢集的可用性。

2.1.1叢集維度

在上面提到的“過半存活即可用”特性中已經講到過,整個叢集如果對外要可用的話,那麼叢集中必須要有過半的機器是正常工作並且彼此之間能夠正常通訊。基於這個特性,那麼如果想搭建一個能夠允許F臺機器down掉的叢集,那麼就要部署一個由2xF+1 臺機器構成的ZK叢集。因此,一個由3臺機器構成的ZK叢集,能夠在down掉一臺機器後依然正常工作,而5臺機器的叢集,能夠對兩臺機器down掉的情況容災。注意,如果是一個6臺機器構成的ZK叢集,同樣只能夠down掉兩臺機器,因為如果down掉3臺,剩下的機器就沒有過半了。基於這個原因,ZK叢集通常設計部署成奇數臺機器。

所以,為了儘可能地提高ZK叢集的可用性,應該儘量避免一大批機器同時down掉的風險,換句話說,最好能夠為每臺機器配置互相獨立的硬體環境。舉個例子,如果大部分的機器都掛在同一個交換機上,那麼這個交換機一旦出現問題,將會對整個叢集的服務造成嚴重的影響。其它類似的還有諸如:供電線路,散熱系統等。其實在真正的實踐過程中,如果條件允許,通常都建議嘗試跨機房部署。畢竟多個機房同時發生故障的機率還是挺小的。

2.1.2單機維度

對於ZK來說,如果在執行過程中,需要和其它應用程式來競爭磁碟,CPU,網路或是記憶體資源的話,那麼整體效能將會大打折扣。
首先來看看磁碟對於ZK效能的影響。客戶端對ZK的更新操作都是永久的,不可回退的,也就是說,一旦客戶端收到一個來自server操作成功的響應,那麼這個變更就永久生效了。為做到這點,ZK會將每次更新操作以事務日誌的形式寫入磁碟,寫入成功後才會給予客戶端響應。明白這點之後,你就會明白磁碟的吞吐效能對於ZK的影響了,磁碟寫入速度制約著ZK每個更新操作的響應。為了儘量減少ZK在讀寫磁碟上的效能損失,不仿試試下面說的幾點:

  • 使用單獨的磁碟作為事務日誌的輸出(比如我們這裡的ZK叢集,使用單獨的掛載點用於事務日誌的輸出)。事務日誌的寫效能確實對ZK效能,尤其是更新操作的效能影響很大,所以想辦法搞到一個單獨的磁碟吧!ZK的事務日誌輸出是一個順序寫檔案的過程,本身效能是很高的,所以儘量保證不要和其它隨機寫的應用程式共享一塊磁碟,儘量避免對磁碟的競爭。
  • 儘量避免記憶體與磁碟空間的交換。如果希望ZK能夠提供完全實時的服務的話,那麼基本是不允許作業系統觸發此類swap的。因此在分配JVM堆大小的時候一定要非常小心,具體在本文最後的“注意事項”章節中有講到。

2.2日常運維

對zookeeper運維是一個長期積累經驗的過程,希望以下幾點對廣大ZK運維人員有一定的幫助:

  • 清理資料目錄

上文中提到dataDir目錄指定了ZK的資料目錄,用於儲存ZK的快照檔案(snapshot)。另外,預設情況下,ZK的事務日誌也會儲存在這個目錄中。在完成若干次事務日誌之後(在ZK中,凡是對資料有更新的操作,比如建立節點,刪除節點或是對節點資料內容進行更新等,都會記錄事務日誌),ZK會觸發一次快照(snapshot),將當前server上所有節點的狀態以快照檔案的形式dump到磁碟上去,即snapshot檔案。這裡的若干次事務日誌是可以配置的,預設是100000,具體參看下文中關於配置引數“snapCount”的介紹。
考慮到ZK執行環境的差異性,以及對於這些歷史檔案,不同的管理員可能有自己的用途(例如作為資料備份),因此預設ZK是不會自動清理快照和事務日誌,需要交給管理員自己來處理。這裡是我們用的清理方法,保留最新的66個檔案,將它寫到crontab中,每天凌晨2點觸發一次:

#!/bin/bash

#snapshot file dir
dataDir=/home/yinshi.nc/test/zk_data/version-2
#tran log dir
dataLogDir=/home/yinshi.nc/test/zk_log/version-2
#zk log dir
logDir=/home/yinshi.nc/test/logs
#Leave 66 files
count=66
count=$[$count+1]
ls -t $dataLogDir/log.* | tail -n +$count | xargs rm -f
ls -t $dataDir/snapshot.* | tail -n +$count | xargs rm -f
ls -t $logDir/zookeeper.log.* | tail -n +$count | xargs rm -f

#find /home/yinshi.nc/taokeeper/zk_data/version-2 -name "snap*" -mtime +1 | xargs rm -f
#find /home/yinshi.nc/taokeeper/zk_logs/version-2 -name "log*" -mtime +1 | xargs rm -f
#find /home/yinshi.nc/taokeeper/logs/ -name "zookeeper.log.*" -mtime +1 | xargs rm –f

其實,僅管ZK沒有自動幫我們清理歷史檔案,但是它的還是提供了一個叫PurgeTxnLog的 工具類,實現了一種簡單的歷史檔案清理策略,可以在這裡看一下他的使用方法:http://zookeeper.apache.org/doc/r3.4.3/api/index.html 簡單使用如下:

java -cp zookeeper.jar:lib/slf4j-api-1.6.1.jar:lib/slf4j-log4j12-1.6.1.jar:lib/log4j-1.2.15.jar:conf org.apache.zookeeper.server.PurgeTxnLog<dataDir><snapDir> -n <count>

最後一個參數列示希望保留的歷史檔案個數,注意,count必須是大於3的整數。可以把這句命令寫成一個定時任務,以便每天定時執行清理。
注意: 從3.4.0版本開始, zookeeper提供了自己清理歷史檔案的功能了,相關的配置引數是autopurge.snapRetainCount和autopurge.purgeInterval,在本文後面會具體說明。更多關於zookeeper的日誌清理,可以閱讀這個文章《ZooKeeper日誌清理》

  • ZK程式日誌

這裡說兩點,ZK預設是沒有向ROLLINGFILE檔案輸出程式執行時日誌的,需要我們自己在conf/log4j.properties中配置日誌路徑。另外,沒有特殊要求的話,日誌級別設定為INFO或以上,我曾經測試過,日誌級別設定為DEBUG的話,效能影響很大!

2.3 Server的自檢恢復

ZK執行過程中,如果出現一些無法處理的異常,會直接退出程式,也就是所謂的快速失敗(fail fast)模式。在上文中有提到,“過半存活即可用”的特性使得叢集中少數機器down掉後,整個叢集還是可以對外正常提供服務的。另外,這些down掉的機器重啟之後,能夠自動加入到叢集中,並且自動和叢集中其它機器進行狀態同步(主要就是從Leader那裡同步最新的資料),從而達到自我恢復的目的。
因此,我們很容易就可以想到,是否可以藉助一些工具來自動完成機器的狀態檢測與重啟工作。回答是肯定的,這裡推薦兩個工具:
Daemontools(http://cr.yp.to/daemontools.html) 和 SMF(http://en.wikipedia.org/wiki/Service_Management_Facility),能夠幫助你監控ZK程式,一旦程式退出後,能夠自動重啟程式,從而使down掉的機器能夠重新加入到叢集中去~

2.4 監控

有幾種方法:

  1. ZK提供一些簡單但是功能強大的4字命令,通過對這些4字命令的返回內容進行解析,可以獲取不少關於ZK執行時的資訊。
  2. 用jmx也能夠獲取一些執行時資訊,詳細可以檢視這裡:http://zookeeper.apache.org/doc/r3.4.3/zookeeperJMX.html
  3. 淘寶網已經實現的一個ZooKeeper監控——TaoKeeper,已開源,在這裡: http://rdc.taobao.com/team/jm/archives/1450,主要功能如下:
  • 機器CPU/MEM/LOAD的監控
  • ZK日誌目錄所在磁碟空間監控
  • 單機連線數的峰值報警
  • 單機Watcher數的峰值報警
  • 節點自檢
  • ZK執行時資訊展示

2.5 日誌管理

ZK使用log4j作為日誌系統,conf目錄中有一份預設的log4j配置檔案,注意,這個配置檔案中還沒有開啟ROLLINGFILE檔案輸出,配置下即可。其它關於log4j的詳細介紹,可以移步到log4j的官網:http://logging.apache.org/log4j/1.2/manual.html#defaultInit

2.6載入資料出錯

ZK在啟動的過程中,首先會根據事務日誌中的事務日誌記錄,從本地磁碟載入最後一次提交時候的快照資料,如果讀取事務日誌出錯或是其它問題(通常在日誌中可以看到一些IO異常),將導致server將無法啟動。碰到類似於這種資料檔案出錯導致無法啟動伺服器的情況,一般按照如下順序來恢復:

  1. 確認叢集中其它機器是否正常工作,方法是使用“stat”這個命令來檢查:echo stat|nc ip 2181
  2. 如果確認其它機器是正常工作的(這裡要說明下,所謂正常工作還是指叢集中有過半機器可用),那麼可以開始刪除本機的一些資料了,刪除$dataDir/version-2和$dataLogDir/version-2 兩個目錄下的所有檔案。

重啟server。重啟之後,這個機器就會從Leader那裡同步到最新資料,然後重新加入到叢集中提供服務。

2.7 配置引數詳解(主要是%ZOOKEEPER_HOME%/conf/zoo.cfg檔案)

引數名

說明

clientPort 客戶端連線server的埠,即對外服務埠,一般設定為2181吧。
dataDir 儲存快照檔案snapshot的目錄。預設情況下,事務日誌也會儲存在這裡。建議同時配置引數dataLogDir, 事務日誌的寫效能直接影響zk效能。
tickTime ZK中的一個時間單元。ZK中所有時間都是以這個時間單元為基礎,進行整數倍配置的。例如,session的最小超時時間是2*tickTime。
dataLogDir 事務日誌輸出目錄。儘量給事務日誌的輸出配置單獨的磁碟或是掛載點,這將極大的提升ZK效能。
(No Java system property)
globalOutstandingLimit 最大請求堆積數。預設是1000。ZK執行的時候, 儘管server已經沒有空閒來處理更多的客戶端請求了,但是還是允許客戶端將請求提交到伺服器上來,以提高吞吐效能。當然,為了防止Server記憶體溢位,這個請求堆積數還是需要限制下的。
(Java system property:zookeeper.globalOutstandingLimit.)
preAllocSize 預先開闢磁碟空間,用於後續寫入事務日誌。預設是64M,每個事務日誌大小就是64M。如果ZK的快照頻率較大的話,建議適當減小這個引數。(Java system property:zookeeper.preAllocSize)
snapCount 每進行snapCount次事務日誌輸出後,觸發一次快照(snapshot), 此時,ZK會生成一個snapshot.*檔案,同時建立一個新的事務日誌檔案log.*。預設是100000.(真正的程式碼實現中,會進行一定的隨機數處理,以避免所有伺服器在同一時間進行快照而影響效能)(Java system property:zookeeper.snapCount)
traceFile 用於記錄所有請求的log,一般除錯過程中可以使用,但是生產環境不建議使用,會嚴重影響效能。(Java system property:?requestTraceFile)
maxClientCnxns 單個客戶端與單臺伺服器之間的連線數的限制,是ip級別的,預設是60(3.4.0開始,預設值調整為60,之前的預設值是10),如果設定為0,那麼表明不作任何限制。請注意這個限制的使用範圍,僅僅是單臺客戶端機器與單臺ZK伺服器之間的連線數限制,不是針對指定客戶端IP,也不是ZK叢集的連線數限制,也不是單臺ZK對所有客戶端的連線數限制。指定客戶端IP的限制策略,這裡有一個patch,可以嘗試一下:http://rdc.taobao.com/team/jm/archives/1334(No Java system property)
clientPortAddress 對於多網路卡的機器,可以為每個IP指定不同的監聽埠。預設情況是所有IP都監聽clientPort指定的埠。New in 3.3.0
minSessionTimeoutmaxSessionTimeout Session超時時間限制,如果客戶端設定的超時時間不在這個範圍,那麼會被強制設定為最大或最小時間。預設的Session超時時間是在2 * tickTime ~ 20 * tickTime這個範圍 New in 3.3.0
fsync.warningthresholdms 事務日誌輸出時,如果呼叫fsync方法超過指定的超時時間,那麼會在日誌中輸出警告資訊。預設是1000ms。(Java system property:fsync.warningthresholdms) New in 3.3.4
autopurge.purgeInterval 在上文中已經提到,3.4.0及之後版本,ZK提供了自動清理事務日誌和快照檔案的功能,這個引數指定了清理頻率,單位是小時,需要配置一個1或更大的整數,預設是0,表示不開啟自動清理功能。(No Java system property) New in 3.4.0
autopurge.snapRetainCount 這個引數和上面的引數搭配使用,這個引數指定了需要保留的檔案數目。預設是保留3個。(No Java system property) New in 3.4.0
electionAlg 在之前的版本中, 這個引數配置是允許我們選擇leader選舉演算法,但是由於在以後的版本中,只會留下一種“TCP-based version of fast leader election”演算法,所以這個引數目前看來沒有用了,這裡也不詳細展開說了。(No Java system property)
initLimit Follower在啟動過程中,會從Leader同步所有最新資料,然後確定自己能夠對外服務的起始狀態。Leader允許F在initLimit時間內完成這個工作。通常情況下,我們不用太在意這個引數的設定。如果ZK叢集的資料量確實很大了,F在啟動的時候,從Leader上同步資料的時間也會相應變長,因此在這種情況下,有必要適當調大這個引數了。(No Java system property)
syncLimit 在執行過程中,Leader負責與ZK叢集中所有機器進行通訊,例如通過一些心跳檢測機制,來檢測機器的存活狀態。如果L發出心跳包在syncLimit之後,還沒有從F那裡收到響應,那麼就認為這個F已經不線上了。注意:不要把這個引數設定得過大,否則可能會掩蓋一些問題。(No Java system property)
leaderServes 預設情況下,Leader是會接受客戶端連線,並提供正常的讀寫服務。但是,如果你想讓Leader專注於叢集中機器的協調,那麼可以將這個引數設定為no,這樣一來,會大大提高寫操作的效能。(Java system property: zookeeper.leaderServes)。
server.x=[hostname]:nnnnn[:nnnnn] 這裡的x是一個數字,與myid檔案中的id是一致的。右邊可以配置兩個埠,第一個埠用於F和L之間的資料同步和其它通訊,第二個埠用於Leader選舉過程中投票通訊。
(No Java system property)
group.x=nnnnn[:nnnnn]weight.x=nnnnn 對機器分組和權重設定,可以 參見這裡(No Java system property)
cnxTimeout Leader選舉過程中,開啟一次連線的超時時間,預設是5s。(Java system property: zookeeper.cnxTimeout)
zookeeper.DigestAuthenticationProvider
.superDigest
ZK許可權設定相關,具體參見使用super身份對有許可權的節點進行操作ZooKeeper許可權控制
skipACL 對所有客戶端請求都不作ACL檢查。如果之前節點上設定有許可權限制,一旦伺服器上開啟這個開頭,那麼也將失效。(Java system property:zookeeper.skipACL)
forceSync 這個引數確定了是否需要在事務日誌提交的時候呼叫FileChannel.force來保證資料完全同步到磁碟。(Java system property:zookeeper.forceSync)
jute.maxbuffer 每個節點最大資料量,是預設是1M。這個限制必須在server和client端都進行設定才會生效。(Java system property:jute.maxbuffer)

2.8 常用的四字命令

引數名

說明

conf 輸出server的詳細配置資訊。New in 3.3.0

$>echo conf|nc localhost 2181
clientPort=2181
dataDir=/home/test/taokeeper/zk_data/version-2
dataLogDir=/test/admin/taokeeper/zk_log/version-2
tickTime=2000
maxClientCnxns=1000
minSessionTimeout=4000
maxSessionTimeout=40000
serverId=2
initLimit=10
syncLimit=5
electionAlg=3
electionPort=3888
quorumPort=2888
peerType=0

cons 輸出指定server上所有客戶端連線的詳細資訊,包括客戶端IP,會話ID等。
New in 3.3.0類似於這樣的資訊:

$>echo cons|nc localhost 2181
/1.2.3.4:43527[1](queued=0,recved=152802,sent=152806,sid=0x2389e662b98c424,lop=PING,
est=1350385542196,to=6000,lcxid=0x114,lzxid=0xffffffffffffffff,lresp=1350690663308,
llat=0,minlat=0,avglat=0,maxlat=483)
……

crst 功能性命令。重置所有連線的統計資訊。New in 3.3.0
dump 這個命令針對Leader執行,用於輸出所有等待佇列中的會話和臨時節點的資訊。
envi 用於輸出server的環境變數。包括作業系統環境和Java環境。
ruok 用於測試server是否處於無錯狀態。如果正常,則返回“imok”,否則沒有任何響應。
注意:ruok不是一個特別有用的命令,它不能反映一個server是否處於正常工作。“stat”命令更靠譜。
stat 輸出server簡要狀態和連線的客戶端資訊。
srvr 和stat類似,New in 3.3.0

$>echo stat|nc localhost 2181
Zookeeper version: 3.3.5-1301095, built on 03/15/2012 19:48 GMT
Clients:
/10.2.3.4:59179[1](queued=0,recved=44845,sent=44845)

Latency min/avg/max: 0/0/1036
Received: 2274602238
Sent: 2277795620
Outstanding: 0
Zxid: 0xa1b3503dd
Mode: leader
Node count: 37473

$>echo srvr|nc localhost 2181
Zookeeper version: 3.3.5-1301095, built on 03/15/2012 19:48 GMT
Latency min/avg/max: 0/0/980
Received: 2592698547
Sent: 2597713974
Outstanding: 0
Zxid: 0xa1b356b5b
Mode: follower
Node count: 37473

srst 重置server的統計資訊。
wchs 列出所有watcher資訊概要資訊,數量等:New in 3.3.0

$>echo wchs|nc localhost 2181
3890 connections watching 537 paths
Total watches:6909

wchc 列出所有watcher資訊,以watcher的session為歸組單元排列,列出該會話訂閱了哪些path:New in 3.3.0

$>echo wchc|nc localhost 2181
0x2389e662b97917f
/mytest/test/path1/node1
0x3389e65c83cd790
/mytest/test/path1/node2
0x1389e65c7ef6313
/mytest/test/path1/node3
/mytest/test/path1/node1

wchp 列出所有watcher資訊,以watcher的path為歸組單元排列,列出該path被哪些會話訂閱著:New in 3.3.0

$>echo wchp|nc localhost 2181
/mytest/test/path1/node
0x1389e65c7eea4f5
0x1389e65c7ee2f68
/mytest/test/path1/node2
0x2389e662b967c29
/mytest/test/path1/node3
0x3389e65c83dd2e0
0x1389e65c7f0c37c
0x1389e65c7f0c364

注意,wchc和wchp這兩個命令執行的輸出結果都是針對session的,對於運維人員來說視覺化效果並不理想,可以嘗試將cons命令執行輸出的資訊整合起來,就可以用客戶端IP來代替會話ID了,具體可以看這個實現:http://rdc.taobao.com/team/jm/archives/1450

mntr 輸出一些ZK執行時資訊,通過對這些返回結果的解析,可以達到監控的效果。New in 3.4.0

$ echo mntr | nc localhost 2185
zk_version 3.4.0
zk_avg_latency 0
zk_max_latency 0
zk_min_latency 0
zk_packets_received 70
zk_packets_sent 69
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count 4
zk_watch_count 0
zk_ephemerals_count 0
zk_approximate_data_size 27
zk_followers 4 - only exposed by the Leader
zk_synced_followers 4 - only exposed by the Leader
zk_pending_syncs 0 - only exposed by the Leader
zk_open_file_descriptor_count 23 - only available on Unix platforms
zk_max_file_descriptor_count 1024 - only available on Unix platforms

2.9 資料檔案管理

預設情況下,ZK的資料檔案和事務日誌是儲存在同一個目錄中,建議是將事務日誌儲存到單獨的磁碟上。

2.9.1資料目錄

ZK的資料目錄包含兩類檔案:

  • myid – 這個檔案只包含一個數字,和server id對應。
  • snapshot. - 按zxid先後順序的生成的資料快照。

叢集中的每臺ZK server都會有一個用於惟一標識自己的id,有兩個地方會使用到這個id:myid檔案和zoo.cfg檔案中。myid檔案儲存在dataDir目錄中,指定了當前server的server id。在zoo.cfg檔案中,根據server id,配置了每個server的ip和相應埠。Zookeeper啟動的時候,讀取myid檔案中的server id,然後去zoo.cfg 中查詢對應的配置。

zookeeper在進行資料快照過程中,會生成 snapshot檔案,儲存在dataDir目錄中。檔案字尾是zxid,也就是事務id。(這個zxid代表了zk觸發快照那個瞬間,提交的最後一個事務id)。注意,一個快照檔案中的資料內容和提交第zxid個事務時記憶體中資料近似相同。僅管如此,由於更新操作的冪等性,ZK還是能夠從快照檔案中恢復資料。資料恢復過程中,將事務日誌和快照檔案中的資料對應起來,就能夠恢復最後一次更新後的資料了。

2.9.2事務日誌目錄

dataLogDir目錄是ZK的事務日誌目錄,包含了所有ZK的事務日誌。正常執行過程中,針對所有更新操作,在返回客戶端“更新成功”的響應前,ZK會確保已經將本次更新操作的事務日誌寫到磁碟上,只有這樣,整個更新操作才會生效。每觸發一次資料快照,就會生成一個新的事務日誌。事務日誌的檔名是log.,zxid是寫入這個檔案的第一個事務id。

2.9.3檔案管理

不同的zookeeper server生成的snapshot檔案和事務日誌檔案的格式都是一致的(無論是什麼環境,或是什麼樣的zoo.cfg 配置)。因此,如果某一天生產環境中出現一些古怪的問題,你就可以把這些檔案下載到開發環境的zookeeper中載入起來,便於除錯發現問題,而不會影響生產執行。另外,使用這些較舊的snapshot和事務日誌,我們還能夠方便的讓ZK回滾到一個歷史狀態。

另外,ZK提供的工具類LogFormatter能夠幫助視覺化ZK的事務日誌,幫助我們排查問題,關於事務日誌的可以化,請檢視這個文章《視覺化zookeeper的事務日誌》.

需要注意的一點是,zookeeper在執行過程中,不斷地生成snapshot檔案和事務日誌,但是不會自動清理它們,需要管理員來處理。(ZK本身只需要使用最新的snapshot和事務日誌即可)關於如何清理檔案,上面章節“日常運維”有提到。

2.10 注意事項

2.10.1 保持Server地址列表一致

  • 客戶端使用的server地址列表必須和叢集所有server的地址列表一致。(如果客戶端配置了叢集機器列表的子集的話,也是沒有問題的,只是少了客戶端的容災。)
  • 叢集中每個server的zoo.cfg中配置機器列表必須一致。

2.10.2 獨立的事務日誌輸出

對於每個更新操作,ZK都會在確保事務日誌已經落盤後,才會返回客戶端響應。因此事務日誌的輸出效能在很大程度上影響ZK的整體吞吐效能。強烈建議是給事務日誌的輸出分配一個單獨的磁碟。

2.10.3 配置合理的JVM堆大小

確保設定一個合理的JVM堆大小,如果設定太大,會讓記憶體與磁碟進行交換,這將使ZK的效能大打折扣。例如一個4G記憶體的機器的,如果你把JVM的堆大小設定為4G或更大,那麼會使頻繁發生記憶體與磁碟空間的交換,通常設定成3G就可以了。當然,為了獲得一個最好的堆大小值,在特定的使用場景下進行一些壓力測試。

相關文章