ZooKeeper是一个开源的分布式协调服务,它为分布式应用提供了高效且可靠的分布式协调服务,并且是分布式应用保证数据一致性的解决方案。该项目由雅虎公司创建,是Google Chubby的开源实现。
分布式应用可以基于ZooKeeper实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁、分布式队列等功能。在越来越多的分布式系统(Hadoop、HBase、Storm、Kafka)中,Zookeeper都作为核心组件使用。
一、准备工作
-
虚拟机相关:
VMware workstation 16:虚拟机 > vmware_177981.zip
CentOS Stream 9:虚拟机 > CentOS-Stream-9-latest-x86_64-dvd1.iso
如果操作系统是win11或者win10家庭版,推荐使用VMware workstation 17版本,网盘地址为:虚拟机 > vmware_17。
-
JDK
jdk1.8:JDK > jdk-8u261-linux-x64.tar.gz
-
Zookeeper
Zookeeper > apache-zookeeper-3.8.4-bin.tar.gz
-
辅助工具
MobaXterm:MobaXterm_Portable_v24.0.zip
本文相关资源可以在文末提供的百度网盘资源中下载,除了vmware(你懂的...),以上资源均来源于官网,MobaXterm是便捷式软件,无需安装。
CentOS的安装、虚拟机克隆、集群网络环境配置可参考 搭建Hadoop3.x完全分布式集群(CentOS 9)安装准备部分。
二、搭建完全分布式集群
Zookeeper的部署方式分为:
- 独立模式(单机模式)
- 集群模式
- 伪分布式模式
- 完全分布模式
本文介绍实际应用场景中的使用的完全分布模式的部署,生产环境一般采用奇数台(大于1)机器组成集群。
ZK节点为什么设置为奇数?
zookeeper有这样一个特性:集群中只要有过半的机器是正常工作的,那么整个集群对外就是可用的。
也就是说如果有2个zookeeper,那么只要有1个服务停止,zookeeper就不能对外提供服务,所以2个zookeeper的死亡容忍度为0;
同理,要是有3个zookeeper, 1个服务停止,还剩下2个正常的,过半了,所以3个zookeeper的容忍度为1;
同理:2 -> 0; 3 -> 1; 4 - >1; 5 -> 2; 6 -> 2会发现一个规律,2n和2n-1的容忍度是一样的,都是n-1,所以为了更加高效,会选择奇数台组成集群。
在进行下面步骤之前,确保已经安装好虚拟机hadoop1、hadoop2、hadoop3,并且已经完成集群的网络环境配置和JDK的安装。
1. 安装Zookeeper
将zookeeper安装包上传至hadoop1虚拟机/software
目录,运行下面命令解压安装:
shell
tar -xvf /software/apache-zookeeper-3.8.4-bin.tar.gz -C /opt
cd /opt
mv apache-zookeeper-3.8.4-bin/ zookeeper-3.8.4
修改配置文件 vi /etc/profile
,添加如下内容:
export ZK_HOME=/opt/zookeeper-3.8.4
export PATH=$PATH:$ZK_HOME/bin
运行source /etc/profile
更新环境变量
2. 修改配置文件
进入虚拟机Hadoop1中ZooKeeper安装目录的conf目录,通过复制ZooKeeper模板文件zoo_sample.cfg创建文件zoo.cfg,再编辑文件zoo.cfg:
shell
cp zoo_sample.cfg zoo.cfg
vi zoo.cfg
修改相应的配置项
#设置数据持久化目录
dataDir=/opt/data/zookeeper/zkdata
#设置客户端连接当前ZooKeeper服务使用的端口号
clientPort=2181
#设置ZooKeeper集群中每个ZooKeeper服务的地址及端口号
server.1=hadoop1:2888:3888
server.2=hadoop2:2888:3888
server.3=hadoop3:2888:3888
参数说明:
参数 默认值 说明 tickTime 2000 Client-Server通信心跳时间 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。tickTime以毫秒为单位。 initLimit 10 Leader-Follower初始通信时限 集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量)。 syncLimit 5 Leader-Follower同步通信时限 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)。 dataDir /tmp/zookeeper 数据文件目录 Zookeeper保存数据的目录,默认情况下,Zookeeper将写数据的日志文件也保存在这个目录里。 clientPort 2181 客户端连接端口 客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。 maxClientCnxns 60 最多支持的客户端连接数 server.id=host:port:port 集群信息 (服务器编号,服务器地址,LF通信端口,选举端口) 这个配置项的书写格式比较特殊,规则如下: server.N=YYY:A:B, 其中N用来表示服务器在集群中的一个序号,我们需要在dataDir目录下创建一个文件 myid
, 文件内容为对应的编号N A为端口号,集群内机器通讯使用(只有Leader监听此端口 B为端口号,用于选举Leader使用(每个Zookeeper都监听此端口)关于参数的更多信息可参考:https://zookeeper.apache.org/doc/r3.7.0/zookeeperAdmin.html#sc_configuration
3. 创建数据持久化目录
根据文件zoo.cfg中参数dataDir指定的值,在虚拟机Hadoop1下执行以下命令,创建数据持久化目录。
shell
mkdir -p /opt/data/zookeeper/zkdata
ssh hadoop2 "mkdir -p /opt/data/zookeeper/zkdata"
ssh hadoop3 "mkdir -p /opt/data/zookeeper/zkdata"
4. 创建myid文件
在虚拟机Hadoop1主机执行以下命令,在数据持久化目录/opt/data/zookeeper/zkdata创建myid文件并分别写入值1、2、3。
shell
echo 1 > /opt/data/zookeeper/zkdata/myid
ssh hadoop2 "echo 2 > /opt/data/zookeeper/zkdata/myid"
ssh hadoop3 "echo 3 > /opt/data/zookeeper/zkdata/myid"
myid
文件标识了该服务器在集群中的唯一ID号,该文件内容就是对应的ID号。ID大小介于1至255,如果开启了扩展特征,比如TTL节点,ID需要介于1至254
5. 分发Zookeeper和环境变量
shell
scp -r /opt/zookeeper-3.8.4 hadoop2:/opt/
scp -r /opt/zookeeper-3.8.4 hadoop3:/opt/
scp -r /etc/profile hadoop2:/etc
scp -r /etc/profile hadoop3:/etc
6. 启动zookeeper集群
在虚拟机Hadoop1上执行以下命令启动ZooKeeper服务。
shell
zkServer.sh start
ssh hadoop2 "source /etc/profile && zkServer.sh start"
ssh hadoop3 "source /etc/profile && zkServer.sh start"
7. 查看启动状态
在虚拟机Hadoop1上执行以下命令查看ZooKeeper集群运行状态。
shell
zkServer.sh status
ssh hadoop2 "source /etc/profile && zkServer.sh status"
ssh hadoop3 "source /etc/profile && zkServer.sh status"
8. 集群服务管理脚本
在虚拟机hadoop1上执行下面的命令,编写zookeeper集群服务管理脚本
shell
cd /opt/zookeeper-3.8.4/bin
touch xzkServer.sh
chmod +x xzkServer.sh
vi xzkServer.sh
编辑如下脚本内容
shell
#!/bin/bash
for host in hadoop1 hadoop2 hadoop3
do
case $1 in
"start"){
echo " "
echo "--------------- 启 动 zookeeper ---------------"
echo "------------ $host zookeeper -----------"
ssh $host "source /etc/profile && zkServer.sh start"
};;
"stop"){
echo " "
echo "--------------- 关 闭 zookeeper ---------------"
echo "------------ $host zookeeper -----------"
ssh $host "source /etc/profile && zkServer.sh stop"
};;
"status"){
echo " "
echo "-------------- 查看zookeeper状态 --------------"
echo "------------ $host zookeeper -----------"
ssh $host "source /etc/profile && zkServer.sh status"
};;
esac
done
三、常见问题及解决办法
1. 端口被占用
错误提示:Address already in use
解决办法:
-
一方面,可以选择停止掉现在占用端口的进程,使用命令
netstat -nltp
并结合命令grep
进行查询 -
另一方面,可以修改zoo.cfg,改变端口号
2. 磁盘空间不够
错误提示:No space left on device
解决办法:清磁盘或者磁盘
3. 无法找到myid文件
错误提示:myid file is missing
解决办法:在dataDir
对应的目录中创建myid文件,并设置正确的内容(服务器对应的id)
4. 集群中其他机器Leader选举端口未开
错误提示:Cannot open channel to 2 at election address /xxx.xxx.xxx.xxx:3888
解决办法:
-
检查各服务器防火墙是否关闭,使用命令
sudo ufw status
-
检查各服务器
/etc/hosts
中的内容是否一致,是否配置了所有节点的ip -
检查各服务器的时间是一致
-
修改各服务器的zoo.cfg,将各自服务器中对应于自己的集群信息中的host修改成
0.0.0.0
比如对示例中的服务器node1,将其zoo.cfg的集群信息修改成
server.1=0.0.0.0:2888:3888 server.2=hadoop2:2888:3888 server.3=hadoop3:2888:3888
5. 最直接最高效的解决办法是分析日志文件
附、网盘资源
链接:https://pan.baidu.com/s/1MSUdwbPArIAglQTDRhOjrg?pwd=jiau
提取码:jiau