服务背景
在现代分布式系统中,协调服务对于确保各个组件之间的同步和通信至关重要。Zookeeper 作为一个高效的分布式协调服务,广泛应用于配置管理、服务发现、分布式锁等场景。在企业中,Zookeeper 常用于构建高可用的分布式应用,例如在大数据处理框架 Hadoop、分布式消息队列 Kafka 等中作为核心的协调服务。
Zookeeper 单点部署
什么是 Zookeeper
Zookeeper 是 Apache 基金会开源的一个顶级项目,主要用于分布式集群的协调服务。其应用场景包括配置中心、注册中心、服务发现等。官网地址:Apache ZooKeeper
下载 Zookeeper 软件包
[root@elk91 ~]# wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
解压软件包
[root@elk91 ~]# tar xf apache-zookeeper-3.8.4-bin.tar.gz -C /usr/local/
创建符号链接
[root@elk91 ~]# ln -svf /usr/local/apache-zookeeper-3.8.4-bin /usr/local/zookeeper
添加环境变量
[root@elk91 ~]# cat /etc/profile.d/zk.sh
#!/bin/bash
export JAVA_HOME=/usr/share/elasticsearch/jdk
export ZK_HOME=/usr/local/zookeeper
export PATH=$PATH:$ZK_HOME/bin:$JAVA_HOME/bin
[root@elk91 ~]# source /etc/profile.d/zk.sh
准备配置文件
[root@elk91 ~]# cp /usr/local/zookeeper/conf/zoo{_sample,}.cfg
启动 Zookeeper 服务
[root@elk91 ~]# zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
验证 Zookeeper 服务状态
[root@elk91 ~]# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: standalone
链接 Zookeeper 服务
[root@elk91 ~]# zkCli.sh
Connecting to localhost:2181
...
[zk: localhost:2181(CONNECTED) 0]
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 1]
测试单点故障
[root@elk91 ~]# zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED
Zookeeper 集群部署
停止 Zookeeper 的单点模式
[root@elk91 ~]# zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED
修改配置文件
[root@elk91 ~]# cat > /usr/local/zookeeper/conf/zoo.cfg <<EOF
# 定义最小单元的时间范围tick。
tickTime=2000
# 启动时最长等待tick数量。
initLimit=5
# 数据同步时最长等待的tick时间进行响应ACK
syncLimit=2
# 指定数据目录
dataDir=/oldboyedu/data/zk
# 监听端口
clientPort=2181
# 开启四字命令允许所有的节点访问。
4lw.commands.whitelist=*
# server.ID=A:B:C[:D]
# ID:
# zk的唯一编号。
# A:
# zk的主机地址。
# B:
# leader的选举端口,是谁leader角色,就会监听该端口。
# C:
# 数据通信端口。
# D:
# 可选配置,指定角色。
server.91=10.0.0.91:2888:3888
server.92=10.0.0.92:2888:3888
server.93=10.0.0.93:2888:3888
## Metrics Providers
#
# <url id="cvdd052ej2dvfs8hchlg" type="url" status="parsed" title="Prometheus - Monitoring system & time series database" wc="532">https://prometheus.io</url> Metrics Exporter
#metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
#metricsProvider.httpHost=0.0.0.0
#metricsProvider.httpPort=7000
#metricsProvider.exportJvmInfo=true
EOF
拷贝软件包到集群的其他节点
[root@elk91 ~]# scp -r /usr/local/zookeeper 10.0.0.92:/usr/local/
[root@elk91 ~]# scp -r /usr/local/zookeeper 10.0.0.93:/usr/local/
[root@elk91 ~]# scp /etc/profile.d/zk.sh 10.0.0.92:/etc/profile.d/
[root@elk91 ~]# scp /etc/profile.d/zk.sh 10.0.0.93:/etc/profile.d/
配置免密登录
[root@elk91 ~]# apt -y install expect
[root@elk91 ~]# cat > password_free_login.sh <<'EOF'
#!/bin/bash
# auther: Jason Yin
# 创建密钥对
ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa -q
# 声明你服务器密码,建议所有节点的密码均一致,否则该脚本需要再次进行优化
export mypasswd=1
# 定义主机列表
elk_list=(10.0.0.91 10.0.0.92 10.0.0.93)
# 配置免密登录,利用expect工具免交互输入
for i in ${elk_list[@]};do
expect -c "
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub root@$i
expect {
\"*yes/no*\" {send \"yes\r\"; exp_continue}
\"*password*\" {send \"$mypasswd\r\"; exp_continue}
}"
done
EOF
[root@elk91 ~]# bash password_free_login.sh
准备 myid 文件
[root@elk91 ~]# for i in `seq 91 93`; do ssh 10.0.0.$i "install -d /oldboyedu/data/zk && echo $i > /oldboyedu/data/zk/myid";done
启动 Zookeeper 集群
[root@elk91 ~]# for i in `seq 91 93`; do ssh 10.0.0.$i "source /etc/profile.d/zk.sh && zkServer.sh start";done
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
验证 Zookeeper 集群状态
[root@elk91 ~]# for i in `seq 91 93`; do ssh 10.0.0.$i "source /etc/profile.d/zk.sh && zkServer.sh status";done
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower
连接集群测试
[root@elk91 ~]# zkCli.sh -server 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181
Connecting to 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181
...
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 0] ls /
[zookeeper]
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 1]
验证 Zookeeper 的高可用
停止 Leader 节点
[root@elk92 ~]# zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED
观察 Leader 变化
[root@elk91 ~]# for i in `seq 91 93`; do ssh 10.0.0.$i "source /etc/profile.d/zk.sh && zkServer.sh status";done
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Error contacting service. It is probably not running.
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader
常见问题及解决方案
问题一:Zookeeper 服务无法启动
问题描述
在启动 Zookeeper 服务时,出现错误:
Error contacting service. It is probably not running.
问题分析
这可能是由于配置文件错误、环境变量未正确设置或端口被占用等原因导致的。
解决方案
-
检查配置文件
zoo.cfg
中的配置是否正确,特别是dataDir
、clientPort
等关键配置。 -
确保环境变量
ZK_HOME
已正确设置,并且PATH
中包含 Zookeeper 的 bin 目录。 -
检查端口 2181 是否被其他服务占用,如有必要,修改
clientPort
配置。 -
检查日志文件
/usr/local/zookeeper/logs/zookeeper.out
,查看是否有更多详细的错误信息。
问题二:Zookeeper 集群节点无法正常通信
问题描述
在集群模式下,部分节点无法正常加入集群,日志中可能出现连接超时或通信错误。
问题分析
这可能是由于网络配置问题、防火墙限制或节点间的时钟不同步等原因导致的。
解决方案
-
检查各节点间的网络连通性,确保节点间可以正常通信。
-
确保防火墙允许 Zookeeper 所需的端口(2181、2888、3888 等)的通信。
-
检查各节点的时钟是否同步,时钟差异可能导致通信问题。
-
检查
zoo.cfg
文件中各节点的配置是否正确,特别是server.ID
的配置。
问题三:Zookeeper 集群的高可用性不足
问题描述
在停止 Leader 节点后,集群无法正常选举出新的 Leader,导致服务中断。
问题分析
这可能是由于集群节点数量不足,无法满足 Zookeeper 的高可用性要求。
解决方案
根据 Zookeeper 的高可用性原则,集群节点数量应为奇数,且最少需要 3 个节点。如果要容忍 N 台节点故障,则需要准备 2N+1 台服务器。例如,要容忍 1 台节点故障,需要至少 3 台服务器;要容忍 2 台节点故障,需要至少 5 台服务器。
总结
Zookeeper 作为分布式系统的协调服务,在企业中有着广泛的应用。通过合理的配置和管理,可以确保 Zookeeper 集群的稳定运行和高可用性。在部署和使用 Zookeeper 集群时,需要注意网络配置、防火墙设置、节点数量等关键因素,以确保集群的可靠性和性能。