前言:
ZooKeeper集群节点的Leader选举情况分为:
1.ZooKeeper集群启动时的Leader选举
2.Leader主节点死亡恢复时的Leader选举
ZooKeeper集群启动时的Leader选举
当我们进行启动前两个服务器节点之后,选举就会开始 :
前提:
在配置文件中,我们配置参与选举的节点数一共有3个
第一轮选举投票:
(1)一开始最初,每一个节点都会生成自己的一张选票。
选票格式为:(myid . zXid):
1.myid是我们在myid这个文件中进行配置的唯一标识。
在我们搭建zookeeper集群时进行的配置:节点1当时创建这个myid文件时配置的是1 节点2配置的
是2。 以此类推。。。。
2.zXid为事务id。这个事务id的改变是随着对znode节点中的数据进行一系列增删改查的操作而变化
的。当每增加或删除或修改或查询该
节点对应数据的时候;该事务id,zXid都会+1 ;
(2) 那么此时节点1生成的选票为(1,0),节点2生成的选票为(2,0)
(3)然后开始投票,第一轮投票,两个节点都会把自己生成的选票投递给对方。那么此时节点1和节
点2都具有了(1,0)和(2,0)两张选票
(4)互相进行投票之后,开始往投票箱中进行投递选票。
投递规则如下:
1.先进行比较事务id:zXid。zXid大的优先被投递到投票箱中。
为什么选举事务id大的 ?
解释:事务id是随着我们对节点数据增删改查而逐渐+1 递增的,我们知道两个节点的数据是同步
的,那么事务id大的说明数据被记录增删
改查的次数多,说明数据更加真实 更加新 !
2.当事务id一样大时,再进行比较myid。这个myid是我们配置文件时的唯一标识,在我们搭建
zookeeper集群时进行的配置。
(5)当两个节点都把选票投递到投票箱之后。开始检测,发现两个节点投票箱中的票数都是1,相对
于参与选举的节点数(3个)没有过半,所
以要进行第二轮选举
第二轮选举投票:
(1)经过第一轮投票之后。节点1拥有的票为:(1,0)和(2,0) 节点2拥有的票为:(1,0)和(2,0)
(2)第二轮投票的规则:双方节点将手上较大的选票投递出去。但是注意是节点1先投递,节点2后
投递 !!
至于如何比较两张选票谁大谁小?第一轮选举投票的时候说过。
{3}然后节点2优先收到节点1的选票之后会把较大的选票投递到投票箱中,发现自己投票箱中的选
票已经两张了,大于参与选举的节点
数:3个 此时停止选举,节点2为Leader
(4) 经过第二轮投票之后。节点1拥有的票为:(2,0)和(2,0) 节点2拥有的票为:(2,0)和(2,0)
(5)由于已经产生Leader,即使节点3没有参与选举,节点3也会被设置为Follower。
Leader主节点死亡恢复时的Leader选举:
(1)当节点服务器启动,Leader选举完成之后,Leader这个主节点会周期性的不断的向各个
Follower从节点发送心跳(即是ping命令,没有内容的socket(socket就是一个数据包,用来存放传输
的数据的))
(2)当这个Leader主节点有一时刻崩溃了,此时所有的Follower再去进行读取socket时就会出现异
常,所有的Follower会发现socket通道已经关闭,那么此时所有
的子节点都意识到Leader这个主节点已经崩溃死亡了 !
(3)于是所有Follower子节点都会把自己的状态从following转化为looking,looking状态表示进行选
举 (选举的方法等效于上述所描述的启动时选举)
总结:
致敬所有框架设计者,致敬这美妙的设计思想 ,致敬源码 !