ZooKeeper集群安装

1.前提条件

  1. 本次安装基于公司内部修改后的ZooKeeper二进制包进行安装,可能过程和标准安装存在不同。
  2. 安装前确保集群已经完成基础环境配置
  3. 本次安装的ZooKeeper软件版本为:3.5.10

ZooKeeper安装依赖于Java环境,和操作系统版本没有直接关系,所以不对系统发行版进行要求。注意ZooKeeper服务个数应该为奇数个,每个服务都对应不同的节点,为了保证高可用性最少为3个(允许1个节点故障),在大型的生产环境通常会配置5个节点(允许2个节点故障),例如在停掉其中1个节点维护的同时,还可以允许再有1个节点故障。

2.环境和参数准备

  1. 集群中共有3个节点,分别为:node1node2node3
  2. ZooKeeper的安装目录定为:/opt/zookeeper-3.5.10
  3. ZooKeeper的数据目录定为:/data/zookeeper
  4. 服务id定义:ZooKeeper每个服务都会有唯一的id标识,我们用${id}表示,并且定义node1的id为1,node2的id为2,node3的id为3

3.配置及安装

3.1.配置修改

由于ZooKeeper所有节点配置均相同,所以先在集群中1个节点进行配置,然后再将安装文件同步至其他节点即可,先在node1上进行配置,首先解压安装包生成安装目录:

# 在node1上执行
tar -xvzf zookeeper-3.5.10.tar.gz -C /opt
cd /opt/zookeeper-3.5.10

这样就将ZooKeeper安装到既定的目录:/opt/zookeeper-3.5.10下面。

然后在node1上编辑配置文件,相对目录为:conf/zoo.cfg

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
# 设置既定的数据目录
dataDir=/data/zookeeper
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
maxClientCnxns=128
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
autopurge.purgeInterval=1

# 新增ZooKeeper服务器列表和通信端口配置
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888

配置文件的配置项不多,重点修改的是数据目录和服务列表部分,下面简单对配置项进行介绍:

tickTime: 是ZooKeeper中的基本时间单位,所有时间都是以基本单位为刻度进行配置,默认是2000ms

initLimit: 是ZooKeeper用来限制法定数量的followers服务器连接并同步到leader的时间长度,默认为10个时间单位,也就是20s

syncLimit: 限制followers服务和leader之间的同步时间,如果追随服务落后于领导者太远,将会被丢弃,默认是5个单位,也就是10s

dataDir: 存储内存数据快照的目录,默认还会保存事务日志,这里要修改为我们既定的数据目录/data/zookeeper,建议配置单独的存储设备来保证性能。

clientPort: 监听客户端连接的端口,默认是2181

maxClientCnxns: 限制单个客户端和单个ZooKeeper成员服务的最大并发连接,单个客户端按照IP来区分,所以这个不是总的限制,默认值是60,这里增大为128

autopurge.snapRetainCount: 开启后,ZooKeeper自动清除功能会在数据和事务中保留指定个数的近期快照和相应的事务日志,其余部分会清除掉,默认值为3,最小值也为3,如果是集群,那么每个机器都会保留相同的数据。

autopurge.purgeInterval:触发清除任务的时间间隔,单位是小时,默认是1小时自动清除一次。

server.${id}: 这个配置要列出所有的ZooKeeper服务节点,${id}就是上面定义的服务id,必须和节点一一对应,这样ZooKeeper就可以根据自己当前的节点id找到其他的节点实现通信,当前节点id由数据目录中的myid文件定义,这个等下会设置,后面的两个端口号中第一个端口号用于followers连接leader服务使用,第二个则用于leader的选举使用。

以上配置,确认无误后保存。

然后继续在node1上编辑服务文件conf/zookeeper.service,默认如下:

[Unit]
Description=zookeeper
After=network.target local-fs.target

[Service]
User=root
Group=root
Type=forking
ExecStart={{ zookeeper_home }}/bin/zkServer.sh start
ExecStop={{ zookeeper_home }}/bin/zkServer.sh stop
TimeoutSec=90s
RestartSec=10s
Restart=always
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

编写服务文件是为了使用systemd管理ZooKeeper进程,方便服务的启停和运行,手动部署的方式需要将其中的{{ zookeeper_home }}模板替换为实际的安装目录/opt/zookeeper-3.5.10,如下:

[Unit]
Description=zookeeper
After=network.target local-fs.target

[Service]
User=root
Group=root
Type=forking
ExecStart=/opt/zookeeper-3.5.10/bin/zkServer.sh start
ExecStop=/opt/zookeeper-3.5.10/bin/zkServer.sh stop
TimeoutSec=90s
RestartSec=10s
Restart=always
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

然后保存服务文件。

现在相关的配置已经在node1节点上完成配置,需要将ZooKeeper安装目录同步至其他所有节点:

# 在node1上执行 前面的路径/opt/zookeeper-3.5.10后面一定不要加'/'
rsync -av /opt/zookeeper-3.5.10 node2:/opt
rsync -av /opt/zookeeper-3.5.10 node3:/opt

3.2.初始化数据目录并安装服务

在所有的节点创建前面定义的数据目录:

# node1,node2,node3 都需要执行
mkdir -p /data/zookeeper

然后生成各个节点的myid文件,要和当前节点的${id}一致:

# echo ${id} > /data/zookeeper/myid
# node1 执行
echo 1 > /data/zookeeper/myid
# node2 执行
echo 2 > /data/zookeeper/myid
# node3 执行
echo 3 > /data/zookeeper/myid

每个节点定义的${id}都必须和myid一致,而且要和配置文件中的server.${id}对应起来,否则启动后会出现错误。

然后在所有的节点安装服务文件到系统中:

# node1,node2,node3 都需要执行
cp /opt/zookeeper-3.5.10/conf/zookeeper.service /usr/lib/systemd/system

为了方便执行命令还可以将ZooKeeper的bin目录添加至环境变量,当然这一步是可选的:

export PATH=$PATH:/opt/zookeeper-3.5.10/bin

3.3.启动服务

在所有节点上启动ZooKeeper服务:

# 所有节点都需要执行
systemctl start zookeeper.service
# 查看运行状态
systemctl status zookeeper.service

启动之后可以分别查看不同节点上ZooKeeper的角色:

# 1个leader, 其余的都为follower
/opt/zookeeper-3.5.10/bin/zkServer.sh status

测试故障转移方法:首先找到leader角色所在的节点,停止掉服务或者杀掉QuorumPeerMain进程,然后查看另外是否有1个节点的状态由follower变为leader。

测试systemd自动拉起进程:找到任意1个节点,手动杀掉QuorumPeerMain进程,稍等几秒看是否能正常被systemd再次重启,可以通过查看zookeeper.service的日志确定拉起的情况:

journalctl -u zookeeper.service -n 10

image-20220616150109355

最后,如果需要开机启动ZooKeeper服务可以执行:

# 设置开机启动服务
systemctl enable zookeeper.service

FAQ:

1.设置绑定的网卡

默认情况下ZooKeeper会绑定所有的网卡,在多网卡环境下也可以指定要绑定到具体的地址:

clientPortAddress=10.0.0.5

2.设置和客户端的session超时

ZooKeeper和客户端进行会话协商过长或客户端无响应会引起超时,可以修改超时时间的限制:

# 默认情况下最小超时为2个周期即4s, 最大超时时间是20个周期即40s 可以根据实际情况配置
minSessionTimeout=2
maxSessionTimeout=20

3.事务日志单独存放

默认情况下事务日志存放在数据目录中,在大规模的生产环境中,为了提升系统的性能,可以将事务日志存放在独立的设备上,从而不会和数据写入相互影响:

dataLogDir=/mnt/zookeeper/log

Reference:

  1. https://zookeeper.apache.org/doc/r3.5.10/zookeeperStarted.html
  2. https://zookeeper.apache.org/doc/r3.5.10/zookeeperAdmin.html#sc_configuration