文章目录
集群搭建
环境准备
虚拟机下准备三台centos机子,并使用telnet测试三台机子2888、3888端口是否互通。若读者centos系统未安装telnet可使用如下命令进行安装。
yum install telnet-server
yum install telnet.*
搭建步骤
创建zkData文件夹
在zk目录下创建一个zkData文件夹
mkdir zkData
在zkData文件夹下创建一个名为myid的文件
三台虚拟机分别在myid设置一个值,笔者分别在三台虚拟机的myid文件中设置的值为1、2、3
vim myid
修改配置
vim conf/zoo.cfg
添加如下配置
server.1=192.168.1.148:2888:3888
server.2=192.168.1.125:2888:3888
server.3=192.168.1.60:2888:3888
需要对参数进行相关说明
server.A=B:C:D
A即myid
,有说法myid配置范围时1-255,笔者查阅大量资料后发现实际上myid的具体范围只要不能大于 Long.MAX_VALUE 或者小于 Long.MIN_VALUE
且不等于-1即可。
B就是ip地址。
C就是follower与followeri交换信息时所用的端口号。
D是leader挂了之后重新进行选举时所用端口号。
启动服务
每台虚拟机下都在zk目录执行如下命令
./bin/zkServer.sh start
测试
使用如下命令即可查看当前zk集群是否搭建完成,且根据mode我们也能知道这个leader
./bin/zkServer.sh status
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader
选举规则详解
先行概念
关键名词
zxid
zxid一共8个字节,前4个字节用来记录epoch,后文会进行详细介绍。后4个字节则用来记录zxid,每进行一次写请求之后,都进行一次+1操作,当后4个字节不够用的时候,就会使用使前4个字节的地址空间进行一次+1操作。如下所示:
00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111+1
00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000000
epoch
该参数存放在zxid的前4个字节中,每当进行一次选举之后,都会进行一次+1操作。
myid
用户自定义数值,不可重复
sid
即myid
初始化选举流程
概述
每台zk刚刚启动时就进入初始化选举过程,当zk集群建立通信后就会进入LOOKING
阶段(此阶段zk们正在寻找 Leader,处于此阶段的办事处不能对外提供服务),这时候zk们都会发起投票,毫无疑问每台zk对其他zk都不了解,所以都会在选票中选自己为leader,而内容格式大体如下:
sid:我是谁
leader:我选谁
state:我当前的状态
epoch:我当前的 epoch
zxid:我选择的 leader 的最大的事务编号
当每台zk相互交换选票后会将他人选票候选人与自己进行比对,比对顺序是epoch->zxid(写请求次数) ->myid
,即epoch相同比zxid,zxid相同就比myid,总之数值大的赢,当zk发现他人选票的候选人比自己的候选人大之后就会改结果,最终的选票中当有半数以上
的选票指定一台zk为leader时,那台得到半数以上的zk就是leader。不管半数以外的zk是故障没参与选票,还是后来加入,通通都要以经过选票后当上leader的zk为主。
实验印证
如下所示,笔者截取了上文中zoo.cfg的配置,并加以注释说明每台对应的myid值,为了印证上面的说法,我们进行两种实验:
- 实验一:同时开启三台zk,若上述结论正确,则leader是60那台。
- 实验二:先同时开启server1 2,在选票完成后开启server3的zk,若上述结果正确,则server2是leader
#######################cluster##########################
#myid 1
server.1=192.168.1.148:2888:3888
# myid 2
server.2=192.168.1.125:2888:3888
# myid 3
server.3=192.168.1.60:2888:3888
实验1
过程不多赘述,同时开启即可。
实验2
可以看出server2当选为leader
此时我们在开启server3,发现也无济于事,实验得以印证
非初始化选举流程
这种情况出现在leader挂机之后,如上文例,当server3挂掉后,server1 2就会通过3888进行重新选举,比对规则也同上。
实验证实
假设现在leader是server3,我们将server3停掉后,若结论正确,新的leader应该是server2,我们对此进行一次实验
如下所示,server3目前是leader,我们将其停止掉
可以看到server2当选为leader,结论得以印证
zk一键启动和停止脚本编写
case $1 in
"start"){
for i in 192.168.1.148 192.168.1.125 192.168.1.60
do
echo -------------zk $i start-------------
ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start"
done
} ;;
"stop"){
for i in 192.168.1.148 192.168.1.125 192.168.1.60
do
echo -------------zk $i stop-------------
ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh stop"
done
};;
"status"){
for i in 192.168.1.148 192.168.1.125 192.168.1.60
do
echo -------------zk $i status-------------
ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh status"
done
};;
esac
一键启动和停止命令
./zk.sh start
./zk.sh stop
./zk.sh ststus