儘管zookeeper在編程上有很多的阱陷,API也非常的難用,但zookeeper服務本身可以說是很牢靠的了,所以在網上貌似關於運維的文章比較少。
但省心並不代表不會出麻煩,下面總結下zookeeper運維相關的東東。
重要的參考資料
這裏有一個很好的Pdf,介紹了很多zookeeper的東東,作者是zookeeper的committer之一:
http://www.infoq.com/presentations/Misconfiguration-ZooKeeper
另外,這裏有一個總結:http://marcin.cylke.com.pl/blog/2013/03/21/zookeeper-tips/
配置zookeeper開機啓動
首先修改bin/zkEnv.sh,配置ZOO_LOG_DIR的環境變量,ZOO_LOG_DIR是zookeeper日誌輸出目錄,ZOO_LOG4J_PROP是log4j日誌輸出的配置:
- if [ "x${ZOO_LOG_DIR}" = "x" ]
- then
- ZOO_LOG_DIR="$ZOOBINDIR/../logs"
- fi
- if [ "x${ZOO_LOG4J_PROP}" = "x" ]
- then
- ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
- fi
再在/etc/init.d目錄下增加zookeeper1文件,並加個可執行權限:
- cd /etc/init.d
- touch zookeeper1
- chmod +x zookeeper1
- #/bin/sh
- #chkconfig: 2345 20 80
- # description: zookeeper1
- case $1 in
- start) su zookeeper /home/zookeeper/zookeeper345_1/bin/zkServer.sh start ;;
- stop) su zookeeper /home/zookeeper/zookeeper345_1/bin/zkServer.sh stop;;
- status) su zookeeper /home/zookeeper/zookeeper345_1/bin/zkServer.sh status;;
- restart) su zookeeper /home/zookeeper/zookeeper345_1/bin/zkServer.sh restart;;
- *) echo "require start|stop|status|restart" ;;
- esac
如果是想配置Upstart方式的啓動,可以參考:http://blog.csdn.net/hengyunabc/article/details/18967627
zookeeper VIRT虛擬內存佔用過大的問題:
這個和zookeeper的實現有關,參考這裏:http://zookeeper-user.578899.n2.nabble.com/setting-zookeeper-heap-size-td6983511.html
線上的zookeeper的VIRT有30多G,查看了data, dataLog,總共才幾百M。不過一直沒什麼問題。
Unreasonable length的問題:
https://issues.apache.org/jira/browse/ZOOKEEPER-1513目前線上用的是345版本,而zookeeper最後的release版本就是這個,有大概一年多沒更新了。。
這個問題有可能是client嘗試向zookeeper上放超過1M的數據時,出現的。
想修改這個默認配置,則可以修改"jute.maxbuffer"這個環境變量。參考:http://zookeeper.apache.org/doc/r3.3.3/zookeeperAdmin.html
但是我們線上是因爲端口掃描工具造成的,這個就相當地詭異了。停止端口掃描工具之後,就沒有這個問題了。
watches數量多的問題:
dubbo對於每個結點都會watch,導致watch數很多,隨便都幾千個。用wchs,wchc,wchp這些命令可以查看watches的信息,包括總數,每條路徑上的watch的數量。每個client的。
查找不能成功啓動原因:
zookeeper會有很多原因啓動不成功,可以通過:
- ./zkServer.sh start-foreground
另外,通過:
- ./zkServer.sh print-cmd
配置自動清理日誌:
從3.4.0開始,會自動清理日誌了,所以這個通常不用配置。
配置autopurge.snapRetainCount 和 autopurge.purgeInterval 參數。
保留的snapshop的數量,默認是3個,最小也是3.
- autopurge.snapRetainCount=3
- autopurge.purgeInterval=1
另外要注意的是,zookeeper重啓會自動清除zookeeper.out日誌,所以如果出錯要注意先備份這個文件。
配置zookeeper.out的位置及log4j滾動日誌輸出
今天發現線上的bin/zookeeper.out 居然有6G大小。看了下zkServer.sh的代碼,這個zookeeper.out實際上是nohup的輸出。
而nohup的輸出實際上是stdout,stderr的輸出,所以還是zookeepe本身的日誌配置的問題。
研究了下bin/zkServer.sh和conf/log4j.properties,發現zookeeper其實是有日誌相關的輸出的配置,只要定義相關的變量就可以了。
主要是ZOO_LOG_DIR和ZOO_LOG4J_PROP這兩個環境變量:
zkServer.sh裏的:
- if [ ! -w "$ZOO_LOG_DIR" ] ; then
- mkdir -p "$ZOO_LOG_DIR"
- fi
- _ZOO_DAEMON_OUT="$ZOO_LOG_DIR/zookeeper.out"
- nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
- -cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
log4j.properties裏的:
- #
- # Add ROLLINGFILE to rootLogger to get log file output
- # Log DEBUG level and above messages to a log file
- log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
- log4j.appender.ROLLINGFILE.Threshold=${zookeeper.log.threshold}
- log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}
而zkServer.sh會加載zkEnv.sh。
因此,其實修改下bin/zkEnv.sh就可以了:
https://gist.github.com/hengyunabc/61d74672e7a662a5366c
- if [ "x${ZOO_LOG_DIR}" = "x" ]
- then
- ZOO_LOG_DIR="$ZOOBINDIR/../logs"
- fi
- if [ "x${ZOO_LOG4J_PROP}" = "x" ]
- then
- ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
- fi
還可以修改下conf/log4j.properties,設置滾動日誌最多爲10個:
- # Max log file size of 10MB
- log4j.appender.ROLLINGFILE.MaxFileSize=10MB
- # uncomment the next line to limit number of backup files
- log4j.appender.ROLLINGFILE.MaxBackupIndex=10
Too many connections from 錯誤
這個錯誤是因爲同一個IP的zookeeper socket 連接數大於60了。zookeeper server默認限制每個IP最多60個連接。
這個在測試服務器上出現的,因爲測試服務器上太多進程在跑了。。
修改爲:
maxClientCnxns=150
http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_advancedConfiguration
This ZooKeeper instance is not currently serving requests 的錯誤提示
當集羣裏的結點只剩下一臺,或者不足半數時,就會出現這個錯誤提示。
通常在,只啓動第一臺zookeeper時會報這個錯誤。
在zookeeper server的日誌裏,會有類似的日誌:
Exception causing close of session 0x0 due to java.io.IOException: ZooKeeperServer not running
Zookeeper連接速度很慢,Dubbo初始化很慢,應用啓動很慢的問題
發現線下環境遷移到新機器後,應用啓動變得很慢,本來十幾秒啓動的應用,變成幾分鐘才能啓動。
啓動過程沒有報錯,只是Dubbo的註冊信息日誌一直在比較慢地刷。
開始懷疑是網絡問題,但是檢查了iptables沒有開啓,用iptraf查看流量,也不高。機器的空閒內存也足夠。
再檢查Zookeeper的配置,磁盤的空間,應用的dubbo配置,jvm配置,發現都沒有問題。
沒辦法了,用jprofiler來測試下,發現“org.I0Itec.zkclient.ZkClient$1.call”,這個調用耗時比較大。
這樣確認是zookeeper本身比較慢,不是應用的問題。
用下面的zookeeper benchmark工具測試了下性能,發現read速度還可能,create/write速度非常慢,qps只有個位數。
於是問了下運維的同事,原來新機器是用共享磁盤的,所以速度很慢。
而zookeeper每次write請求都要寫到log日誌,並刷到磁盤裏,所以非常的慢。
後來運維的同事換爲本地磁盤,一切恢復正常。
管理工具:
Zookeeper官方自帶的管理員工具:
http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html 官方的命令行工具可以勝任絕大部分工作了。zktop
https://github.com/phunt/zktop python寫的小工具,很有意思taokeeper
項目地址:https://github.com/alibaba/taokeeper
淘寶出品的一個監控工具,還有可以用腳本來監控的功能。雖然開源了,但是實際上很難用,代碼也很難擴展,而且有些jar包是淘寶內部的。
我修改了下,可以正常使用,代碼地址在:https://github.com/hengyunabc/taokeeper
但是我們線上也沒有用這個,線上只有zabbix的監控。
安裝配置參考:
編譯
1.下載這兩個項目:git clone https://github.com/hengyunabc/common-toolkit.git
git clone https://github.com/nileader/zkclient.git
先分別執行 mvn -Dmaven.test.skip install
2.下載本項目:
git clone https://github.com/hengyunabc/taokeeper.git
執行 mvn -Dmaven.test.skip clean package
到taokeeper-monitor/target/目錄就可以看到生成的War包了。
部署
taokeeper使用mysql數據庫來保存一些配置和日誌。導入taokeeper-build/etc/taokeeper.sql 文件,也可以從這裏下載:文件:Taokeeper.sql.zip 。
配置tomcat啓動參數,增加JVM啓動參數:
JAVA_OPTS=-DconfigFilePath="~/taokeeper/taokeeper-monitor-config.properties"
並在上面的配置中配置好參數,例如:
systemInfo.envName=TEST
#DBCP
dbcp.driverClassName=com.mysql.jdbc.Driver
dbcp.dbJDBCUrl=jdbc:mysql://localhost:3306/taokeeper
dbcp.characterEncoding=GBK
dbcp.username=root
dbcp.password=root
dbcp.maxActive=30
dbcp.maxIdle=10
dbcp.maxWait=10000
#SystemConstant
SystemConstent.dataStoreBasePath=~/taokeeper/
#SSH account of zk server
SystemConstant.userNameOfSSH=hello
SystemConstant.passwordOfSSH=hello
其中SSH用戶密碼要配置對,zookeeper部署的機器要開放SSH服務。
把生成的War包改爲ROOT.war,放到tomcat的webapps目錄下,啓動tomcat。
如果報log4j錯誤,則還要配置webapps/ROOT/WEB-INF/classes/log4j.properties 文件。也可以在編繹前先修改好。
打開 http://localhost:8080/ ,就可以看到taokeeper的界面了。
工作原理
taokeeper通過SSH連接到zookeeper部署的機器上,再在上面執行zookeeper的Four Letter Words來得到統計信息,再分析保存到mysql數據庫中。參考:http://zookeeper.apache.org/doc/trunk/zookeeperAdmin.html#sc_zkCommands
監控目標機器的負載,也是通過SSH連接到目標機器,再執行top等命令,再分析得到數據。
注意事項
在chrome瀏覽器下,“機器監控”這個功能有時會把信息顯示下瀏覽器的下面,要拉到最後才能看到,並不是這個功能不能工作。Exhibitor
這個是Netflix出品的一個監控工具,但實際上也很難用。。
Exhibitor的主要功能 監控本機的Zookeeper服務,可以自動重啓掛掉的Zookeeper服務;定期備份數據;
定期清理Zookeeper日誌;
提供了一個Web界面可以修改Zookeeper的數據;
REST API。
Exhibitor安裝
Exhibitor提供了三種運行方式:獨立的jar文件,War包,core jar。推薦用jar方式運行,配置管理都很方便。安裝方法可以參考這裏:https://github.com/Netflix/exhibitor/wiki/Building-Exhibitor,也可以從這裏下載已經編繹好的jar文件:文件:Exhibitor-war-1.0-jar-with-dependencies.zip,下載後要修改後綴爲jar。
運行
java -jar <path>/exhibitor-xxx.jar -c fileExhibitor自動創建配置文件,在web界面所做的配置更改都會保存到exhibitor.properties中。
配置項
參考:https://github.com/Netflix/exhibitor/wiki/Configuration-UI在配置“Servers”參數時,一定要注意要配置的是hostname,而不是IP。所以如果配置的是IP的話,一定要到目標機器上去檢查hostname和IP是否一致。
注意事項
Exhibitor通過jps命令來判斷Zookeeper服務是否運行,所以要配置好jps命令,如果沒有當前沒有jps命令的話,可以通過類似如下的命令創建一個軟鏈接:ls -s /home/www/jdk/jdk1.7.0_15/bin/jps /usr/bin/jps
Exhibitor會自動創建並覆蓋zookeeper的配置文件,所以要在Web界面上把Zookeeper的所有參數都配置,
否則如果Zookeeper被Exhibitor重啓後,可以會出現因爲配置有錯誤而無法啓動的狀況。
在“control panel”面板中,當顯示綠色,則說明Zookeeper服務正常,可以對外服務,當顯示黃色或者紅色,
則Zookeeper不能對外提供服務(這個和Zookeeper進程是否存在,是兩個概念,即使Zookeeper進程存在,也可能無法對外提供服務)。
Exhibitor會定時探測Zookeeper服務是否正常,但是時間間隔默認配置爲0,這個會導致機器CPU被消耗。要在Web界面中配置好“Live Check (ms)”參數。
因爲Exhibitor如果探測到Zookeeper服務沒有啓動,會自動啓動Zookeeper進程,所以在升級Zookeeper之前,要先停掉Exhibitor。
其它的一些東東:
性能測試相關:
https://github.com/brownsys/zookeeper-benchmark
這個工具輸出結果比較亂,不過用起來還不錯。
mvn -DZooKeeperVersion=3.4.5 package
./runBenchmark.sh test
然後在test文件夾下,會有生成的信息。主要在zk-benchmark.log這個文件裏。