zookeeper运维(hengyunabc)
来源:http://blog.csdn.net/hengyunabc/article/details/19006911
分类: zookeeper Java 2014-02-09 15:06 3506人阅读 评论(0) 收藏 举报
尽管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
-
再修改zookeeper1的内容为:
#/bin/sh #chkconfig: 2345 20 80 # description: zookeeper1 zkServer=/home/zookeeper/zookeeper345_1/bin/zkServer.sh zkUser=zookeeper case $1 in start) su $zkUser $zkServer start;; stop) su $zkUser $zkServer stop;; status) su $zkUser $zkServer status;; restart) su $zkUser $zkServer restart;; *) echo "$0 start|stop|status|restart";; esac
最后用chkconfig -add zookeeper1
增加服务。这样就搞定了。注意用su zookeeper来切换到zookeeper用户。
如果是想配置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
目前线上用的是3.4.5版本,而zookeeper最后的release版本就是这个,有大概一年多没更新了。
这个问题有可能是client尝试向zookeeper上放超过1M的数据时,出现的。
想修改这个默认配置,则可以修改jute.maxbuffer
这个环境变量。参考:http://zookeeper.apache.org/doc/r3.3.3/zookeeperAdmin.html
jute.maxbuffer: (Java system property: jute.maxbuffer) This option can only be set as a Java system property. There is no zookeeper prefix on it. It specifies the maximum size of the data that can be stored in a znode. The default is 0xfffff, or just under 1M. If this option is changed, the system property must be set on all servers and clients otherwise problems will arise. This is really a sanity check. ZooKeeper is designed to store data on the order of kilobytes in size. 每个节点最大数据量,是默认是1M。这个限制必须在server和client端都进行设置才会生效。(Java system property:jute.maxbuffer)
但是我们线上是因为端口扫描工具造成的,这个就相当地诡异了。停止端口扫描工具之后,就没有这个问题了。
watches数量多的问题
dubbo对于每个结点都会watch,导致watch数很多,随便都几千个。
用wchs,wchc,wchp这些命令可以查看watches的信息,包括总数,每条路径上的watch的数量。每个client的。
查找不能成功启动原因
zookeeper会有很多原因启动不成功,可以通过:
./zkServer.sh start-foreground
来查看启动时报的是什么异常,同时也可以查看运行过程中的异常。 另外,通过:
./zkServer.sh print-cmd
可以查看zookeeper启动的各个参数,包括java路径等,也可以便于查找问题。
配置自动清理日志
从3.4.0开始,会自动清理日志了,所以这个通常不用配置。
配置autopurge.snapRetainCount
和 autopurge.purgeInterval
参数。
保留的snapshop的数量,默认是3个,最小也是3。
autopurge.snapRetainCount=3 autopurge.purgeInterval=1
参考这里:http://nileader.blog.51cto.com/1381108/932156
另外要注意的是,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
maxClientCnxns (No Java system property) Limits the number of concurrent connections (at the socket level) that a single client, identified by IP address, may make to a single member of the ZooKeeper ensemble. This is used to prevent certain classes of DoS attacks, including file descriptor exhaustion. The default is 60. Setting this to 0 entirely removes the limit on concurrent connections.
剩余节点不足错误
当集群里的结点只剩下一台,或者不足半数时,就会出现这个错误:
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连接及写入非常慢
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的监控。
-
Exhibitor:这个是Netflix出品的一个监控工具,但实际上也很难用。。Exhibitor的主要功能:
- 监控本机的Zookeeper服务,可以自动重启挂掉的Zookeeper服务;
- 定期备份数据;
- 定期清理Zookeeper日志;
- 提供了一个Web界面可以修改Zookeeper的数据;
- REST API。
taokeeper安装配置
-
编译
- 下载这两个项目:
- 先分别执行 mvn -Dmaven.test.skip install
-
下载本项目:
- 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安装
-
Exhibitor的主要功能
- 监控本机的Zookeeper服务,可以自动重启挂掉的Zookeeper服务;
- 定期备份数据;
- 定期清理Zookeeper日志;
- 提供了一个Web界面可以修改Zookeeper的数据;
- REST API。
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 file
Exhibitor自动创建配置文件,在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。
其它的一些东东
性能测试相关
这个工具输出结果比较乱,不过用起来还不错。
mvn -DZooKeeperVersion=3.4.5 package ./runBenchmark.sh test
然后在test文件夹下,会有生成的信息。主要在zk-benchmark.log这个文件里。
- http://zookeeper.apache.org/doc/r3.4.5/zookeeperOver.html
- http://wiki.apache.org/hadoop/ZooKeeper/ServiceLatencyOverview 自带的文档里有一点,不过貌似没更新过
- http://wiki.apache.org/hadoop/ZooKeeper/ServiceLatencyOverview Hadoop里带的一个测试
- https://ramcloud.stanford.edu/wiki/display/ramcloud/ZooKeeper+Performance
- http://rdc.taobao.com/team/jm/archives/1070 淘宝的一个测试