1. 什么是zookeeper
什么是zookeeper呢, 使用官方的话是分布式远程协调服务
那为什么要有zookeeper呢? 到底是解决了什么问题呢???
上述是我们分布式部署架构. 我们会把会员系统
等服务独立部署. 但是很少能有服务独立完成工作的, 所以肯定会牵扯服务之间的相互调用.
但是依据上述服务架构而言的话, 肯定会在服务内部写死IP/ 域名. 服务之间都是正常运行还好,一旦牵扯服务宕机的话, 一是: 必须手动做出反应 二是: 启动一个新的服务,牵扯到的其余服务都必须手动修改IP/ 域名等
可以理解为服务之间是强耦合的. 这个时候我们就需要有别的服务来管理所有的服务. 只需要告诉调用者, 被调用服务是否存在, 是否可以正常调用就行了. 基于这种服务治理的目的, zookeeper
出现了
所以就连zookeeper
logo 都是一个人, 用来治理协调服务的
1.1 zookeeper 实现要点
- 为别的分布式程序服务的
- 本身就是一个分布式程序
- 主从协调 服务器节点动态上下线 统一配置管理 分布式共享锁 统一名称服务
- 管理(存储,读取)用户程序提交的数据 并为用户程序提供数据节点监听服务
本身zookeeper
就是管理 以及治理服务的, 所以其本身的高可用
不言而喻, 所以一般我们部署的时候, 直接就是上集群. 接下来我们会对集群做重点描述
2. zookeeper 详解
2.1 集群机制
zookeeper的集群机制采用的是半数存活机制,也就是整个集群节点中有半数以上的节点存活,那么整个集群环境可用。这也就是说们的集群节点最好是奇数个节点
在这里可能会有人好奇, 为什么是奇书节点呢???
首先我们要理解, 如果存活机制是半数存活机制
, 说明 运行的节点 > 总节点/ 2的
如果是三台节点的话, 详情看下图:
部署的节点为三台的话, 如果一台服务器宕机了, 整个架构还是属于正常运行状态, 如果两台宕机了, 整个集群服务都宕机了
如果是四台节点的话, 详情看下图:
如果部署的节点是四台的话, 如果一台服务器宕机了,整个架构还是属于正常运行状态, 如果两台宕机了,整个集群服务都宕机了
综上所属, 同样的宕机频率, 实现同样的部署, 还是奇数台节点更加节省服务资源
2.2 集群节点角色
- Leader
- 事务请求的唯一调度和处理者,保证集群事务处理的顺序性
- 集群内部各服务器的调度者
- Follower
- Follower是Zookeeper集群的跟随者
- 处理客户端非事务性请求(读取数据),转发事务请求给Leader服务器
- 参与事务请求Proposal的投票
- 参与Leader选举投票
2.3 集群模式
2.3.1 服务器准备
下面是准备的三台服务器
192.168.56.10
192.168.56.11
192.168.56.12
2.3.2 配置NDS 以及静态站点
这里配置静态站点, 避免了手动输入IP的痛苦, 毕竟在TCP过程解析域名的时候, 可以自主解析出IP的
vi /etc/hosts
# 列表为添加内容
192.168.56.10 vagrant01
192.168.56.11 vagrant02
192.168.56.12 vagrant03
通过上述截图可以看到, 是可以ping
通的.
2.3.3 建立免密 密钥
创建密钥, 避免服务器之间发送内容的时候 需要登录
输入命令ssh-keygen
, 不停的输入回车
cd ~/.ssh
- 执行命令
ssh-copy-id vagrant01
- 循环上述步骤2 执行
ssh-copy-id vagrant02``ssh-copy-id vagrant03
2.3.4 关闭防火墙
firewall-cmd --state
查看防火墙状态systemctl stop firewall.service
停止防火墙systemctl disable firewall.service
禁止开机启动
2.3.5 下载以及解压zookeeper
创建目录
mkdir -p ~/soft
cd ~/soft
执行命令
sudo wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.1/apache-zookeeper-3.8.1-bin.tar.gz --no-check-certificate
通过命令tar -xf
进行解压, 解压后通过命令mv
进行名称修改
2.3.6 修改配置文件
执行命令 cd ~/soft/zookeeper/conf
vi zoo.cfg
修改配置文件名称
创建myid
配置文件
我们需要在Zookeeper的数据存储的目录中创建一个myid文件,文件中的内容只有一行信息,即表示我们集群几点的标识,范围是1-255,每个节点的myid的数字和我们在zoo.cfg中配置的server.数字是对应的
执行命令
mkdir -p ~/soft/zookeeper/data
cd ~/soft/zookeeper/data
echo 1 > myid
2.3.7 相同的配置 远程发送别的服务
最好保证 别的服务也拥有相同的文件夹. 例如:
/home/vagrant/soft
执行如下命令
cd ~/soft
scp -r zookeeper vagrant02:
pwd``scp -r zookeeper vagrant03:
pwd``
修改服务vagrant02``vagarnt03
中的myid
文件内容
2.3.8 path 目录中配置JAVA_HOME
- 将jdk 压缩包上传到文件夹
/home/vagrant/soft
- 执行命令 解压
tar -xf jdk-8u361-linux-x64.tar.gz
- 修改名称 执行命令
mv jdk1.8.0_361 jdk1.8
- 执行命令
sudo vi /etc/profile.d/jdk.setup.sh
, 将下列内容 复制到文件内
#!/bin/bash
JAVA_HOME=/home/vagrant/soft/jdk1.8
export PATH=$PATH:${JAVA_HOME}/bin
- 重启配置文件
source /etc/profile
上述是以服务
vagrant01
来进行演示, 将服务vagrant02
以及vagrant03
执行同样的步骤
2.3.9 启动zookeeper 服务
执行如下命令 启动服务
cd ~/soft/zookeeper/bin
./zkServer.sh start
服务vagrant02``vagrant03
执行相同的命令
3. zookeeper 选举策略
3.1 为什么要Leader选举
- Leader 主要作用是保证分布式数据一致性,即每个节点的存储的数据同步。遇到以下两种情况需要进行Leader选举
- 服务器初始化启动
- 服务器运行期间无法和leader 保持连接, leader节点崩溃
3.2 初期化选举leader
leader 的选举有两个关键性的字段:
SID``ZXID
SID
表示每个节点配置文件myid
的数字ZXID
表示业务id, 表示数据更新程度, 值越大, 表示服务对ZNode
操作越新
- 每个Server投出一票。他们两都选自己为Leader,投票的内容为(SID,ZXID). 由于服务器初始化,
每个Sever上的Znode为0,所以Server1投的票为(1,0),Server2为(2,0) - 两Server将各自投票发给集群中其他机器
- 每个Server接收来自其他Server的投票。集群中的每个Server先判断投票有效性,
如检查是不是本轮的投票,是不是来Looking状态的服务器投的票 - 对投票结果进行处理。先了解下处理规则
- 首先对比ZXID。ZXID大的服务器优先作为Leader
- 若ZXID相同,比如初始化的时候,每个Server的ZXID都为0
- 就会比较myid,myid大的选出来做Leader
- 对于Server而言,他接受到的投票为(2,0),因为自身的票为(1,0),所以此时它会选举Server2为Leader,将自己的更新为(2,0)。而Server2收到的投票为Server1的(1,0)由于比他自己小,
Server2的投票不变。Server1和Server2再次将票投出,投出的票都为(2,0) - 统计投票。每次投票之后,服务器都会统计投票信息,如果判定某个Server有过半的票数投它,
那么该Server将会作为Leader。对于Server1和Server2而言,统计出已经有两台机器接收了(2,0)的投票信息,此时认为选出了Leader
3.3 运行时选举leader
Zookeeper运行期间,如果有新的Server加入,或者非Leader的Server宕机,那么Leader将会同步数据到新Server或者寻找其他备用Server替代宕机的Server。若Leader宕机,此时集群暂停对外服务,开始在内部选举新的Leader。
假设当前集群中有Server1、Server2、Server3三台服务器,Server2为当前集群的Leader,由于意外情况,Server2宕机了,便开始进入选举状态
- 变更状态。其他的非Observer服务器将自己的状态改变为Looking,开始进入Leader选举
- 每个Server发出一个投票(myid,ZXID),由于此集群已经运行过,所以每个Server上的ZXID可能不同。假设Server1的ZXID为145,Server3的为122,第一轮投票中,Server1和Server3都投自己,
票分别为(1,145)、(3,122),将自己的票发送给集群中所有机器 - 每个Server接收接收来自其他Server的投票,接下来的步骤与初始化时相同
所以我们在上述zookeeper 部署
过程中, 如果是按配置顺序启动的话, 一定是第二台服务器 是leader
. 因为在ZXID
相同的情况下, 第二台服务的myid
比 第一台大.
因为已经选择出leader
, 所以第三台服务不会参与竞选, 只会进行数据同步