1.简介
zookeeper是Apache软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。
zookeeper的架构通过冗余服务实现高可用性。
zookeeper的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。
一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。
2.Zookeeper原理
2.1Zookeeper数据结构
zookkeeper提供的名称空间非常类似于标准文件系统,key-value的形式存储。名称key由斜线/分割的一系列路径元素,zookeeper名称空间中的每个节点都是由一个路径标识。
2.2CAP理论
CAP理论指出对于一个分布式计算系统来说,不可能同时满足以下三点:
●一致性:在分布式环境中,一致性是指数据在多个副本之间是否能够保持一致的特性,等同于所有节点访问同一份最新的数据副本。在一致性的需求下,当一个系统在数据一致的状态下执行更新操作后,应该保证系统的数据仍然处于一致的状态。
●可用性:每次请求都能获取到正确的响应,但是不保证获取的数据为最新数据。
●分区容错性:分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障。
一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。
在这三个基本需求中,最多只能同时满足其中的两项,P是必须的,因此只能在CP和AP中选择,zookeeper保证的是CP,对比spring cloud系统中的注册中心eruka实现的是AP。
2.3BASE理论
BASE是Basically Available(基本可用)、Soft-state(软状态)和Eventually Consistent(最终一致性)三个短语的缩写。
●基本可用:在分布式系统出现故障,允许损失部分可用性(服务降级、页面降级)。
●软状态:允许分布式系统出现中间状态。而且中间状态不影响系统的可用性。这里的中间状态是指不同的 data replication(数据备份节点)之间的数据更新可以出现延时的最终一致性。
●最终一致性:data replications 经过一段时间达到一致性。
BASE理论是对CAP中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。
3.部署Zookeeper集群
上面简单介绍了zookeeper相关概念,下面让我们来部署zookeeper集群。
三台CentOS7虚拟机:
组件名称 | IP/域名 | 端口 |
zookeeper1 | 192.168.18.200 | 2181 |
zookeeper2 | 192.168.18.201 | 2181 |
zookeeper3 | 192.168.18.202 | 2181 |
Java版本:java version "11.0.17"
3.1下载Zookeeper
官网下载地址https://downloads.apache.org/zookeeper/,我下载是3.7.1版本(这里有个坑,官网给了两个安装包,其中“apache-zookeeper-3.7.1.tar.gz”是源码,我们要下载“apache-zookeeper-3.7.1-bin.tar.gz”这个编译后二进制包才对):
可以通过wget命令下载或者手动下载。安装包我是手动下载然后通过工具上传到linux服务器上自定义/root/package目录中。
3.2部署Java环境
因为部署zookeeper需要java环境,所以需要从Oracle官网https://www.oracle.com/cn/java/technologies/downloads/#java11下载jdk安装部署,我下载版本是java11版本,下载版本截图如下:
具体部署shell脚本如下:
# 新建java目录
mkdir /usr/java
# 切换到安装包目录
cd /root/package
# 解压jdk二进制安装包到java目录下
tar zxvf jdk-11.0.17_linux-x64_bin.tar.gz -C /usr/java
# 删除java文件夹
rm -rf /usr/java/jdk1.8.0_351
# 分发java目录到201和202服务器对应目录上
scp -r /usr/java/jdk-11.0.17 root@192.168.18.201:/usr/java/jdk-11.0.17
scp -r /usr/java/jdk-11.0.17 root@192.168.18.202:/usr/java/jdk-11.0.17
# 编辑profile文件配置java环境变量
vi /etc/profile
# 插入
i
{
# 配置java环境变量
export JAVA_HOME=/usr/java/jdk-11.0.17
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
# 配置zookeeper环境变量
export ZOOKEEPER_HOME=/root/zookeeper/apache-zookeeper-3.7.1-bin
# 配置path环境变量
export PATH=$PATH:${JAVA_PATH}:$ZOOKEEPER_HOME/bin
}
# 保存退出
:wq
# 查看PATH环境变量的值
echo $PATH
# 刷新profile文件使其java环境变量生效
source /etc/profile
# 查看java版本号
java -version
3.3部署Zookeeper集群
上面步骤zookeeper二进制包已下载、java环境已部署,可以通过以下shell脚本部署zookeeper集群:
# 新建zookeeper目录
mkdir /root/zookeeper
# 移除zookeeper版本目录
rm -rf /root/zookeeper/apache-zookeeper-3.7.1-bin
# 切换到安装包目录
cd /root/package
# 解压zookeeper安装包到其目录下
tar zxvf apache-zookeeper-3.7.1-bin.tar.gz -C /root/zookeeper
# 用户可以使用mv命令来为文件或目录改名或将文件由一个目录移入另一个目录中
mv $ZOOKEEPER_HOME/conf/zoo_sample.cfg $ZOOKEEPER_HOME/conf/zoo.cfg
# 创建zookeeper数据目录
mkdir $ZOOKEEPER_HOME/data
# 创建zookeeper日志目录
mkdir $ZOOKEEPER_HOME/logs
# 编辑zookeeper配置文件
vi $ZOOKEEPER_HOME/conf/zoo.cfg
# 插入
i
{
# 配置zookeeper数据目录
dataDir=/root/zookeeper/apache-zookeeper-3.7.1-bin/data
# 配置zookeeper日志目录
dataLogDir=/root/zookeeper/apache-zookeeper-3.7.1-bin/logs
# 配置zookeeper集群,如果是阿里云服务器,当前节点要配置成0.0.0.0:2888:3888
server.1=192.168.18.200:2888:3888
server.2=192.168.18.201:2888:3888
server.3=192.168.18.202:2888:3888
}
# 保存退出
:wq
# 编辑myid文件,设置zookeeper集群ID,注意集群ID不能重复,集群节点可以依次1、2、3如此类推设置
vi $ZOOKEEPER_HOME/data/myid
# 插入
i
{
1
}
# 保存退出
:wq
# 分发zookeeper目录到201和202服务器对应目录上
scp -r /root/zookeeper/apache-zookeeper-3.7.1-bin root@192.168.18.201:/root/zookeeper/apache-zookeeper-3.7.1-bin
scp -r /root/zookeeper/apache-zookeeper-3.7.1-bin root@192.168.18.202:/root/zookeeper/apache-zookeeper-3.7.1-bin
# 如果防火墙有IP端口限制,请设置端口允许外部访问
firewall-cmd --permanent --zone=public --add-port=2888/tcp
firewall-cmd --permanent --zone=public --add-port=3888/tcp
firewall-cmd --permanent --zone=public --add-port=2181/tcp
# 从防火墙里移除IP端口
firewall-cmd --permanent --zone=public --remove-port=2888/tcp
firewall-cmd --permanent --zone=public --remove-port=3888/tcp
firewall-cmd --permanent --zone=public --remove-port=2181/tcp
# 防火墙重启
firewall-cmd --reload
# 查看端口是否允许外部访问
firewall-cmd --permanent --zone=public --query-port=2888/tcp
firewall-cmd --permanent --zone=public --query-port=3888/tcp
# 查看防火墙所有端口
firewall-cmd --zone=public --list-ports
# 启动zk服务:
sh /root/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh start
# 停止zk服务:
sh /root/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh stop
# 重启zk服务:
sh /root/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh restart
# 查看zk服务状态:
sh /root/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh status
# 打开zookeeper服务新的session会话
sh /root/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkCli.sh
# 查看zookeeper集群节点信息
ls /otter/组件名称/destinations/组件实例名称/1001/cursor
# 获取zookeeper集群节点信息
get /otter/组件名称/destinations/组件实例名称/1001/cursor
# 设置zookeeper集群节点信息
set /otter/组件名称/destinations/组件实例名称/1001/cursor {"@type":"com.alibaba.otter.canal.protocol.position.LogPosition","identity":{"slaveId":-1,"sourceAddress":{"address":"xx","port":3306}},"postion":{"gtid":"","included":false,"journalName":"mysql-bin.007419","position":4,"serverId":2504145825,"timestamp":1651049385000}}
# 删除zookeeper集群节点信息
delete /otter/组件名称/destinations/组件实例名称/1001/cursor
3.4Zookeeper自启动
为了解决服务器宕机重启后zookeeper节点集群手动启动问题,加入自启动shell脚本:
# 切换到/etc/rc.d/init.d目录,该目录下的脚本就类似与windows中的注册表,在系统启动的时候执行
cd /etc/rc.d/init.d
# 查看当前所处的目录
pwd
# 修改文件或者目录的时间属性,包括访问时间和修改时间,若文件不存在,系统会建立一个新的文件
touch zookeeper
# 给执行权限
chmod +x zookeeper
# 编辑zookeeper自启动执行文件
vi /etc/rc.d/init.d/zookeeper
# 插入
i
{
#!/bin/bash
#chkconfig:2345 20 90
#description:zookeeper
#processname:zookeeper
export JAVA_HOME=/usr/java/jdk-11.0.17
case $1 in
start) su root /root/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh start;;
stop) su root /root/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh stop;;
status) su root /root/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh status;;
restart) su /root/zookeeper/apache-zookeeper-3.7.1-bin/bin/zkServer.sh restart;;
*) echo "require start|stop|status|restart" ;;
esac
}
# 保存退出
:wq
# 刷新zookeeper文件使其生效
source /etc/rc.d/init.d/zookeeper
# chkconfig命令用于检查,设置系统的各种服务。它可查询操作系统在每一个执行等级中会执行哪些系统服务,其中包括各类常驻服务。
# 列出chkconfig所知道的所有的服务的情况
chkconfig --list
# chkconfig新增zookeeper后台服务
chkconfig --add zookeeper
# chkconfig开启zookeeper后台服务
chkconfig zookeeper on
参考文献:
Zookeeper官网 https://zookeeper.apache.org/
Zookeeper教程 https://www.runoob.com/w3cnote/zookeeper-tutorial.html
Zookeeper-QuickStart https://github.com/alibaba/canal/wiki/Zookeeper-QuickStart