Zookeeper 集群部署与管理实践
服务背景
在现代分布式系统中,协调服务对于确保各个组件之间的同步和通信至关重要。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 < # 定义最小单元的时间范围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 # # #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 集群时,需要注意网络配置、防火墙设置、节点数量等关键因素,以确保集群的可靠性和性能。