四、zookeeper集群搭建与选举规则详解

集群搭建

环境准备

虚拟机下准备三台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值,为了印证上面的说法,我们进行两种实验:

  1. 实验一:同时开启三台zk,若上述结论正确,则leader是60那台。
  2. 实验二:先同时开启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

参考文献

集群选举流程

CentOS7关闭防火墙设置命令

猜你喜欢

转载自blog.csdn.net/shark_chili3007/article/details/120619573