视频汇总首页:http://edu.51cto.com/lecturer/index/user_id-4626073.html



ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务


Zookeeper在TDBank中的使用场景

【干货】zookeeper 运营经验分享_第1张图片

TDBank主要利用zookeeper实现配置管理、配置更新通知、节点主备容灾、节点心跳管理等。使用到的模块包括消息中间件Tube、流式处理平台storm、分拣中心TDSort及配置管理中心TDManager,各模块利用zookeeper的功能如下


Tube

【干货】zookeeper 运营经验分享_第2张图片

我们利用zookeeper实现Tube的master进行主、备容灾,实现master的高可用性;另外,利用zookeeper保存各消费者的消费offset信息;


Storm

【干货】zookeeper 运营经验分享_第3张图片

Storm的所有的状态信息都是保存在Zookeeper里面,nimbus通过在zookeeper上面写状态信息来分配任务,supervisor,task通过从zookeeper中读状态来领取任务,同时supervisor, task也会定义发送心跳信息到zookeeper,使得nimbus可以监控整个storm集群的状态,从而可以重启一些挂掉的task。ZooKeeper 使得整个storm集群十分的健壮,任何一台工作机器挂掉都没有关系,只要重启然后从zookeeper上面重新获取状态信息就可以了。


TDSort和TDManager

【干货】zookeeper 运营经验分享_第4张图片

TManager和TDSort通过zookeeper实现配置的共享和配置更新的通知。TDManager定时将业务配置写入zookeeper,TDSort将从zookeeper中读取业务配置并对数据进行分拣。当TDManager对业务配置更新后,它同样通过zookeeper通知TDSort更新内存中的配置。通过zookeeper,TDBank实现几千个分拣进程共享配置。


Zookeeper部署

为了确保ZooKeeper服务的稳定与可靠性,我们通常是将zk搭建成一个集群来对外提供服务,因此这里主要介绍zk集群的部署。


Zookeeper集群有一个很重要的特性:集群中的zk节点只要有过半存活,集群就能正常工作。基于这个特性,建议将ZK集群的机器数量控制为奇数较为合适。当集群的机器个数是3个时,允许最多一台机器宕机;当集群的机器个数是5个时,最多允许2台机器同时宕机,以此类推……当然,并不是机器个数越多越好,机器越多虽然可以提供集群的吞吐量,但是带来的代价是一致性同步时间更长,大家可以根据业务的特性来确定机器的个数。TDBank的业务场景既要吞吐量,也需要一致性同步耗时短,因此我们使用5台机器搭建集群。


确定机器的个数后,我们下一步需要选择机型和机器。我们建议选择含有多块硬盘的机型,这样可以把zookeeper的数据文件和事务日志分别放存到不同的盘,以免两者抢占IO,影响zookeeper节点工作。对于机器,如果条件允许,建议选择的zookeeper机器分布在不同机架,选择不同机架是为了防止机架掉电造成zk服务中断。如果条件允许,也可尝试跨机房部署,多个机房同时发生故障的机率会更小的,但跨机房需要考虑网络质量,包括网络延时及IDC中断等情况。TDBank综合自身场景,选择了公司的TS4机型,TS4使用的方法:将11块盘中10块拆成两组,每组5块盘,分别作软raid10,将数据文件和事务日志分别放存到不同的raid10组中;我们的机器分布在同一个机房的5个不同机架。


Zookeeper集群的搭建步骤包括如下:

1、安装JDK,配置JAVA环境,执行java –version和javac –version命令来确定环境是否OK;


2、选择合适的zookeeper版本,并把对应的包上传到各台机器;

http://www.apache.org/dyn/closer.cgi/zookeeper/


3、在各台zookeeper的conf目录下建立一个zoo.conf,在同一个集群中,各台机器的zoo.conf内容一致,内容示例如下

【干货】zookeeper 运营经验分享_第5张图片


备注:/data0和/data1分别属于不同的挂载点;zoo1至zoo5分别为5台不同的zookeeper机器,建议使用域名,更方便维护;集群中的每台机器都需要感知整个集群是由哪几台机器组成的,在配置文件中,可以按照这样的格式,每行写一个机器配置:server.id=host:port:port. 关于这个id,我们称之为Server ID,标识host机器在集群中的机器序号


4、在每台机器建立dataDir和dataLogDir目录,同时在每台机器的dataDir下建立文件myid,文件的内容为配置1,2,3,4…,具体值跟上面提到的ServerID一致,例子中的zoo1机器中的myid内容为1,zoo5机器中的myid内容为5


5、至此,配置已完成,接下来逐台启动zookeeper进程,进入%ZK_HOME%/bin,执行

./zkServer.sh start


6、验证是否启动成功,进入%ZK_HOME%/bin,执行下面命令,就可以连接上zookeeper;

./zkCli.sh


当然,也可以使用下面命令快速确定节点的状态

echo stat|netcat localhost 2181


Zookeeper监控

对于zookeeper的监控,我们可以使用zk提供的4字命令返回的内容进行解析监控


当然,你也可以使用淘宝的开源工具TaoKeeper进行监控。Zookeeper的监控包括下面几个方面:


1、机器的CPU、内存、负载、硬盘IO利用率等基础监控,这些均可以网管系统实现;


2、ZK日志目录所在磁盘空间监控,这可以针对性的监控;


3、各节点的进程监控,配置自动拉起等;


4、各节点的连接数监控,配置峰值告警;


5、各节点的Watcher数监控,配置峰值告警;


6、使用四字命令,对每个节点进行检查,确保进程不僵死;


7、节点存活个数监控;


Zookeeper数据及日志维护

Zookeeper的数据文件存放在配置中指定的dataDir中,每个数据文件名都以snapshot开头,每个数据文件为zookeeper某个时刻数据全量快照。在zookeeper中,对数据的更新操作,包括创建节点、更新节点内容、删除节点都会记录事务日志,zookeeper在完成若干次事务日志(snapCount)后会生成一次快照,把当前zk中的所有节点的状态以文件的形式dump到硬盘中,生成一个snapshot文件。这里的事务次数是可以配置,默认是100000个。


Zookeeper的日志包括两个部分,一部分是系统日志,另一部分是事务日志。


系统日志使用log4j进行管理,conf目录中有一个log4j配置文件,该配置文件默认没有打开滚动输出,需要用户自己配置,具体请参看log4j介绍。


事务日志默认存放在dataDir中,当然可以使用dataLogDir指定存放的位置。正常运行过程中,针对所有更新操作,在返回客户端“更新成功”的响应前,ZK会确保已经将本次更新操作的事务日志写到磁盘上,只有这样,整个更新操作才会生效。每触发一次数据快照,就会生成一个新的事务日志。


默认情况下,zk不会自动清理数据文件和日志文件,因此需要管理员自己清理。我们可以使用ZK的工具类PurgeTxnLog进行清理,当然,我们也可以写脚本自己维护,同时可以使用工具慢慢清理,避免占用大量IO。清理脚本如下:

【干货】zookeeper 运营经验分享_第6张图片


务必注意:如果长时间不清理,切忌同一时间使用rm命令同时删除大量文件,这样会造成IO利用率瞬间飙升,zookeeper的连接会出现断连或session超时,影响现网业务使用。


另外,对于每一个数据文件,它都是某一时刻的完整快照,我们可以定时将该文件备份,方便对数据进行还原或将zookeeper直接迁移到另外一个集群。


Zookeeper常用命令

命令行下连接zookeeper

bin/zkCli.sh -server zoo1:2181,zoo2:2181,zoo3:2181,zoo4:2181,zoo5:2181

查看子节点ls /

创建节点create /node data

删除节点delete /node

设置节点值,set /node data1

命令行下连接zookeeper并将结果打印到控制台

bin/zkCli.sh -server zoo1:2181,zoo2:2181,zoo3:2181,zoo4:2181,zoo5:2181 get /data/test

常用的四字命令

四字命令的用法为echo 四字命令|netcat localhost 2181

例如输出server的配置信息echo conf|netcat localhost 2181


【干货】zookeeper 运营经验分享_第7张图片【干货】zookeeper 运营经验分享_第8张图片

Zookeeper优化建议

对于zookeeper的优化,有下面几点建议:


1、将zookeeper与其他应用分开部署,避免相互影响;


对于zookeeper来说,如果在运行过程中,需要和其它应用程序来竞争磁盘、CPU、网络、内存资源,那么整体性能将会大打折扣。我们在使用zookeeper初期尝试将zookeeper与其他应用公用机器,在系统流量上涨后,由于IO及CPU被其他应用使用很大,造成zookeeper的session经常超时甚至应用与zookeeper的连接断开。因此,建议zookeeper与其他应用分开部署;


2、将数据文件和事务日志分开存放,提高zookeeper性能;


我们先分析一下磁盘对zookeeper性能的影响。客户端对ZK的更新操作都是永久的,不可回退的。为做到这点,ZK会将每次更新操作以事务日志的形式写入磁盘,写入成功后才会给予客户端响应。明白这点之后,你就会明白磁盘的吞吐性能对于ZK的影响了,磁盘写入速度制约着ZK每个更新操作的响应。因此,我们在选择机型时尽量选择多块硬盘的机器,ZK的事务日志输出是一个顺序写文件的过程,本身性能是很高的,所以尽量保证不要和其它随机写的应用程序共享一块磁盘,尽量避免对磁盘的竞争。


3、尽量避免内存与磁盘空间的交换,确保设置一个合理的JVM堆大小;


如果设置太大,会让内存与磁盘进行交换,这将使ZK的性能大打折扣。例如一个4G内存的机器的,如果你把JVM的堆大小设置为4G或更大,那么会使频繁发生内存与磁盘空间的交换,通常设置成3G就可以了。

【干货】zookeeper 运营经验分享_第9张图片