1、选举机制的概述
半数机制
:集群中半数以上机器存活,集群可用,所以zookeeper适合在奇数台机器上
,zookeeper虽然在配置文件没有说master/slave
,zookeeper工作是一个节点为leader,其他的为follow,leader是选举出来的(内部有选举机制
)
2、Zookeeper的第一次启动的选举
服务器初始化
拿三台服务器
组成的zookeeper集群为例,各自的myid为1-3,它们都是最新启动
的,之前没有历史数据
,看看它们之间的选举是咋样的,下图是依次启动
2.1、选举过程分析
(1)服务器Server1
启动,发起一次选举。服务器Server1
投自己一票,此时服务器Server1
票数1票,不够半数以上(3/2 + 1 =2
),选举无法完成,服务器Server1
状态为LOOKING
(2)服务器Server2
启动,再次发起一次选举。服务器Server1
和服务器Server2
分别投自己一票,并且交换投票信息
,此时服务器Server1
发现服务器Server2
的myid比自己的(服务器Server1
)的myid大,更改选票为推举服务器Server2(把自己的票数给服务器Server2)
,此时服务器Server1和服务器Sever2票数为0,2,票数超过一半以上,服务Server2当选Leader,服务器Server1为following,服务器Server2为leader
(3)服务器Server3启动,发起一次选举。这时服务器Server1和服务器Server2状态分别为following
、Leading
,不会更改选票的信息(因为已经选出Leader,不在观察myid大小
)服务器Server3为following(小弟)
注意
:当集群服务器有5台
时,前面的服务器1和服务器2,都是LOOKING,服务器1票数为0,服务器2票数为2,当启动第三台服务器时,服务器3的myid大,服务器2会把票数给服务器3,(服务器启动会给自己投一票
)这时服务器3票数为3选为Leader,其他的都是following,之后启动的服务器也是following
2.2、zookeeper选举机制中的概念
1)服务器状态
LOOKING
:选举中,正在寻找LeaderFOLLOWING
:随从状态,同步leader状态,参与投票Leader
:领导者,差不多是master,在zookeeper中只有leader才有写的权限,following只有读的权限OBSERVING
:观察者状态,不同leader状态,不参与投票
FOLLOWING状态主要具备以下几个功能
:向leader发送请求
(PING消息、request消息、ACK消息
,REVALIDATE消息)接收leader消息并处理
- 接收client发送过来的请求,如果为写请求,会发送给Leader进行投票处理,然后返回client结果
2)ServerId:服务器ID 和服务器的myid一致
比如有三台服务器,编号分别是1,2,3(myid
里面的值)编号越大在选择算法中的权重越重
3)Zxid:事务ID
服务器中存放的最大数据ID;值越大说明数据越新,在选举算法中数据越新权重越大
用来标识
一次服务器状态的变更.,在某个时刻集群中的每台机器的Zxid的值不一定完全一致,这个和zookeeper服务器对于客户端的更新的请求
的逻辑有关了
4)Epoch:逻辑时钟
每个Leader任期的代号
。或者可以叫投票的次数
,没有Leader时统一轮投票过程中的逻辑时钟值相同的,每投完一次票这个数据就会增加
,然后与接收到的其他的服务器返回的投票信息中的数值相比
,根据不同的值做出不同的判断。
3、Zookeeper的非第一次启动的选举
服务器运行期间无法和leader保持连接
这时服务器(无法和leader保持连接的
)会发起选举流程
,当前集群可能会处于以下两种状态:
集群中本来存在leader
或者集群中确实不存在leader
3.1、集群中存在leader
集群中存在leader,就是,它无法连接上leader而已,所以它(无法连接leader的服务器
)发起leader选举
处理:会被告知
当前服务器的leader的信息
,对于该机器来说,仅仅需要和leader机器建立连接
,并进行状态同步
即可
3.2、集群确实不存在leader
4、Zookeeper集群搭建
三台服务器集群案例:
注意
:首先必须安装好jdk
1)解压安装 在对应的目录下,比如:/usr/local/software
tar -zxvf apache-zookeeper-3.7.0-bin.tar.gz
修改目录为zookeeper:
mv apache-zookeeper-3.7.0 jdk
2)在/usr/local/software/zookeeper目录下创建一个zkData目录和log目录,并在zkData下创建myid文件,写入Server号
mkdir zkdata
mkdir log
# 在zkData创建myid文件,写入Server号 比如2
vim myid
注意
:上下不要有空行,左右不要有空格
3)将zookeeper目录下的conf的zoo_sample.cfg 修改
为 zoo.cfg,并对配置信息修改
# 修改名称
mv zoo_sample.cfg zoo.cfg
# 打开并且配置信息
vim zoo.cfg
# 配置信息
dataDir=/usr/local/software/zookeeper/zkData
dataLogDir=usr/local/software/zookeeper/log
4)增加如下配置
集群信息
server.2=192.168.43.131:2888:3888
server.3=192.168.43.131:2888:3888
server.4=192.168.43.131:2888:3888
参数解读:
server.A=B:C:D
A是一个数字,表示这个是第几号服务器(myid的值
)
集群模式
下配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面有一个数据
就是 A 的值,Zookeeper 启动时读取此文件
(myid),拿到里面的数据与 zoo.cfg 里面的配置信息比
较从而判断到底是哪个 server
B:是这个服务器的地址
C:是这个服务器Follow与集群中的leader服务器的交换信息端口号
D:是万一集群中的leader服务器挂了
,需要一个端口来重新进行选举
,选出一个新的leader,而这个端口就是用来执行选举时服务器相互通信的端口
为什么可以一样
:因为在三台服务器上
,端口不会冲突
(要是伪集群
,就会出现端口占用情况
)
在三台配置中都配置以上信息,就可以了
5) 分别启动Zookeeoper
bin/zkServer.sh start
【说明
】:zoo.cfg的配置信息的详细介绍
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/tmp/zookeeper
clientPort=2181
tickTime
:zookeeper的时间单位
,单位是ms,就是2s,后面的时间都是以tickTime为基础单位
initLimt
:允许follower
连接并且同步Leader的初始化
连接时间(10*2000ms)
syncLimit
:允许Leader与follower之间发消息
和应答时间
限制【数据同步
】(超过这时间就认为follower掉线不等
)
dataDir
:存储
zookeeper数据
和日志
路径
clientPort
:客户端连接服务器端口(默认是2181)