zookeeper集群搭建
ZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效、高可用的分布式协调服务,提供了诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知和分布式锁等分布式基础服务。 由于 ZooKeeper 便捷的使用方式、卓越的性能和良好的稳定性,被广泛地应用于诸如 Hadoop、HBase、Kafka 和 Dubbo 等大型分布式系统中。
Zookeeper 有三种运行模式:单机模式
、伪集群模式
和集群模式
。这里我们以集群模式
为例进行介绍。 集群模式最重要的一点是,只要集群中存在超过一半的机器能够正常工作,那么整个集群就能够正常对外服务。正是基于这个特性,要将 ZK 集群的节点数量要为奇数
(2n+1:如 3、5、7 个节点)较为合适。
1. 准备Java环境
2. 下载、解压
下载 zookeeper-3.4.12.tar.gz
到指定目录:
复制代码
wget -P /home/{$user}/software https://archive.apache.org/dist/zookeeper/zookeeper-3.4.12/
解压到安装目录
复制代码
tar -zxvf zookeeper-3.4.12.tar.gz -C /home/{$user}/zookeeper
3. 创建目录
在各 zookeeper 节点目录下创建以下目录:
复制代码
cd /home/{$user}/zookeeper/zookeeper-3.4.12 mkdir data mkdir logs
4. 创建myid文件
在各服务器节点(server-01
、server-02
、server-03
)的 dataDir 目录下创建名为 myid 的文件,在文件第一行写上对应的 Server id。这个id必须在集群环境中服务器标识中是唯一的,且大小在1~255之间。
复制代码
server-01: echo "1" > myid server-02: echo "2" > myid server-03: echo "3" > myid
5. 修改配置
将 zookeeper-3.4.12/conf 目录下的 zoo_sample.cfg 文件拷贝一份,命名为 zoo.cfg
复制代码
cp zoo_sample.cfg zoo.cfg
修改zoo.cfg
配置文件 (3台机器都需要,可以先配置好一台,然后通过 scp 等命令复制到其它服务器节点)
复制代码
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/home/{$user}/zookeeper/zookeeper-3.4.12/data dataLogDir=/home/{$user}/zookeeper/zookeeper-3.4.12/logs autopurge.snapRetainCount=10 autopurge.purgeInterval=1 clientPort=2181 server.1=IP1:2881:3881 server.2=IP2:2882:3882 server.3=IP3:2883:3883
参数说明:
-
tickTime=2000
Zookeeper最小时间单元,单位为ms
,默认值为3000。也就是Leader与Follower每隔tickTime时间就会发送一个心跳。 -
initLimit=10
Leader服务器等待Follower启动并完成数据同步的时间,默认值10。 当已经超过10*tickTime后,Leader还没有收到Follower的返回信息,那么表明这个Follower连接或同步失败。 -
syncLimit=5
Leader服务器和Follower之间进行心跳检测的最大延时时间,默认值5,最长不能超过5*tickTime -
dataDir=/home/{$user}/zookeeper/zookeeper-3.4.12/data
存放内存数据结构的snapshot,便于快速恢复,默认情况下,事务日志也会存储在这里。建议同时配置参数dataLogDir, 事务日志的写性能直接影响zk性能。 -
dataLogDir=/home/{$user}/zookeeper/zookeeper-3.4.12/data
dataLogDir事务日志输出目录。为了达到性能最大化,一般建议把dataDir和dataLogDir分到不同的磁盘上,这样就可以充分利用磁盘顺序写的特性。 -
autopurge.purgeInterval, autopurge.snapRetainCount
客户端在与zookeeper交互过程中会产生非常多的日志,而且zookeeper也会将内存中的数据作为snapshot保存下来,这些数据是不会被自动删除的,这样磁盘中这样的数据就会越来越多。不过可以通过这两个参数来设置,让zookeeper自动删除数据。autopurge.purgeInterval:指定自动清理快照文件和事务日志文件的时间,单位为
h
,默认为0
表示不自动清理,这个时候可以使用脚本zkCleanup.sh手动清理。如果不清理则磁盘空间占用越来越大。autopurge.snapRetainCount:用于指定保留快照文件和事务日志文件的个数,默认为3。
不过如果你的集群是一个非常繁忙的集群,然后又碰上这个删除操作,可能会影响zookeeper集群的性能,所以一般会让这个过程在访问低谷的时候进行,但是遗憾的是zookeeper并没有设置在哪个时间点运行的设置,所以有的时候我们会禁用这个自动删除的功能,而在服务器上配置一个cron,然后在凌晨来干这件事。
-
clientPort=2181
顾名思义,就是客户端连接zookeeper服务的端口。这是一个TCP port。 -
server.
id
=IP/Host
:port1
:port2
id:用来配置ZK集群中的各节点,并建议id的值和myid保持一致。
IP/Host: 服务器的 IP 或者是与 IP 地址做了映射的主机名
port1:Leader和Follower或Observer交换数据使用
port2:用于Leader选举注意
:如果是伪集群的配置方式,不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。 -
maxClientCnxns
对于一个客户端的连接数限制,默认是60,这在大部分时候是足够了。
但是在我们实际使用中发现,在测试环境经常超过这个数,经过调查发现有的团队将几十个应用全部部署到一台机器上,以方便测试,于是这个数字就超过了 -
minSessionTimeout, maxSessionTimeout
一般,客户端连接zookeeper的时候,都会设置一个session timeout,如果超过这个时间client没有与zookeeper server有联系,则这个session会被设置为过期(如果这个session上有临时节点,则会被全部删除,这就是实现集群感知的基础,后面的文章会介绍这一点)。
但是这个时间不是客户端可以无限制设置的,服务器可以设置这两个参数来限制客户端设置的范围。
6. 开放防火墙端口
在防火墙中打开要用到的端口 2181、2881、3881
切换到 root 用户权限,执行以下命令:
复制代码
chkconfig iptables on service iptables start
编辑/etc/sysconfig/iptables
复制代码
vi /etc/sysconfig/iptables
如server-01 增加以下 3 行:
复制代码
## zookeeper -A INPUT -m state --state NEW -m tcp -p tcp --dport 2181 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 2881 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 3881 -j ACCEPT
重启防火墙:
复制代码
service iptables restart
查看防火墙端口状态:
复制代码
service iptables status
7. 启动并测试
如果使用普通用户启动则到 /home/{$user}/zookeeper/node-0X/bin 目录中执行:
复制代码
./zkServer.sh start
显示:
复制代码
ZooKeeper JMX enabled by default Using config: /home/{$user}/zookeeper/zookeeper-3.4.12/bin/../conf/zoo.cfg Starting zookeeper ... STARTED
输入 jps 命令查看进程:
复制代码
jps
显示:
复制代码
xxxx QuorumPeerMain
其中,QuorumPeerMain 是 zookeeper 进程,说明启动成功。
查看状态:
复制代码
./zkServer.sh status
显示:
复制代码
ZooKeeper JMX enabled by default Using config: /home/{$user}/zookeeper/zookeeper-3.4.12/bin/../conf/zoo.cfg Mode: leader(或者follower)
查看 zookeeper 服务输出信息:
服务信息输出文件在/home/{$user}/zookeeper/zookeeper-3.4.12/bin/zookeeper.out
复制代码
tailf zookeeper.out
8. 停止 zookeeper 进程
复制代码
./zkServer.sh stop
9. 配置 zookeeper 开机使用 {$user} 用户启动
编辑 server-01、sersver-02、server-03 中的 /etc/rc.d/rc.local
文件,分别加入:
复制代码
export JAVA_HOME={$JAVA_HOME} su - {$user} -c '/home/{$user}/zookeeper/zookeeper-3.4.12/bin/zkServer.sh start'
10. 基本命令
登录ZookeeperClient:
复制代码
./zkCli.sh -server ip:port
ip: 可以为Leader,也可以为Follower的ip或主机名
port: 2181为ZooKeerp提供的客户端服务端口。
进入ZooKeeper命令行操作界面后,输入help然后回车,可以看到ZooKeeper支持的命令列表:
复制代码
[zk: localhost:2181(CONNECTED) 0] help ZooKeeper -server host:port cmd args stat path [watch] set path data [version] ls path [watch] delquota [-n|-b] path ls2 path [watch] setAcl path acl setquota -n|-b val path history redo cmdno printwatches on|off delete path [version] sync path listquota path rmr path get path [watch] create [-s] [-e] path data acl addauth scheme auth quit getAcl path close connect host:port
11. zookeeper各类日志简介
zookeeper服务器会产生三类日志:事务日志、快照日志和log4j日志。
在zookeeper默认配置文件zoo.cfg(可以修改文件名)中有一个配置项dataDir,该配置项用于配置zookeeper快照日志和事务日志的存储地址。
在官方提供的默认参考配置文件zoo_sample.cfg中,只有dataDir配置项。其实在实际应用中,还可以为事务日志专门配置存储地址,配置项名称为dataLogDir,在zoo_sample.cfg中并未体现出来。在没有dataLogDir配置项的时候,zookeeper默认将事务日志文件和快照日志文件都存储在dataDir对应的目录下。
建议将事务日志(dataLogDir)与快照日志(dataLog)单独配置,因为当zookeeper集群进行频繁的数据读写操作是,会产生大量的事务日志信息,将两类日志分开存储会提高系统性能,而且,可以允许将两类日志存在在不同的存储介质上,减少磁盘压力。
dataDir:存在一个文件夹version-2,该文件夹中保存着数据快照日志文件。如:acceptedEpoch、currentEpoch dataLogDir:存在一个文件夹version-2,该文件夹中保存着事物日志文件。如:log.*
log4j用于记录zookeeper集群服务器运行日志,该日志的配置地址在conf/目录下的log4j.properties文件中,该文件中有一个配置项为“zookeeper.log.dir=.”,表示log4j日志文件在与执行程序zkServer.sh在同一目录下。当执行zkServer.sh时,在该文件夹下会产生zookeeper.out日志文件。
12. 修改 Zookeeper 日志 zookeeper.out 输出路径
如果不做修改,默认zookeeper的日志输出信息都打印到了zookeeper.out文件中,这样输出路径和大小没法控制,因为日志文件没有轮转。所以需要修改日志输出方式。具体操作如下:
-
修改 ZOOKEEPER_HOME/bin/zkEnv.sh
将:ZOO_LOG_DIR="."
改为:ZOO_LOG_DIR="/home/{$user}/zookeeper/logs"
再修改下ZOO_LOG4J_PROP,让日志不是输出到zookeeper.out,而是写入到日志文件
将:ZOO_LOG4J_PROP="INFO,CONSOLE"
改为:ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
-
修改: ZOOKEEPER_HOME/conf/log4j.properties
-
如果按日志文件大小轮转,只需执行一步
zookeeper.root.logger=INFO,ROLLINGFILE
-
如果按照天轮转,需执行以下两步
1)log4j.appender.ROLLINGFILE=org.apache.log4j.DailyRollingFileAppender
2) zkEnv.sh:注释掉# log4j.appender.ROLLINGFILE.MaxFileSize=10MB
-
-
修改 /opt/zookeeper-3.4.6/bin/zkServer.sh(可选)
可不修改该文件,只是zk的启动脚本默认用 nohup 启动会生成一个zookeeper.out的空文件
若修改则执行以下两步:
1) 注释以下行:复制代码
#_ZOO_DAEMON_OUT="$ZOO_LOG_DIR/zookeeper.out" # nohup "$JAVA" "-Dzookeeper.log.dir......... # -cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN.........
2) 添加该行:
复制代码
"$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" -cp "$CLASSPATH" $J