10、zookeeper的leader选举
服务器状态
-
looking
:寻找leader
状态。当服务器处于该状态时,它会认为当前集群中没有leader
,因此需要进入leader
选举状态 -
following
:跟随着状态。表明当前服务器角色是follower
-
observing
:观察者状态。表明当前服务器角色是observer
分为两种选举,服务器启动时的选举和服务器运行时期的选举
在集群初始化节点,当有一台服务器server1
启动时,其单独无法进行和完成leader
选举,当第二台服务器server2
启动时,此时两台及其可以相互通信,每台及其都试图找到leader
,于是进入leader
选举过程。选举过程如下:
myid:配置集群时的服务id ,server.x
-
每个
server
发出一个投票。由于是初始状态,server1
和server2
都会将自己作为leader
服务器来进行投票,每次投票都会包含所推举的myid
和zxid
,使用(myid,zxid
),此时server1
的投票为(1,0),server2
的投票为(2,0),然后各自将这个投票发给集群中的其它机器 -
集群中的每台服务器都接收来自集群中各个服务器的投票
-
处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行pk,规则如下
-
优先检查
zxid
。zxid
比较大的服务器优先作为leader
(zxid
较大者保存的数据更多) -
如果
zxid
相同。那么就比较myid
。myid
较大的服务器作为leader
服务器对于
Server1
而言,它的投票是(1,0),接收Server2
的投票为(2,0),首先会比较两者的zxid
,均为0,再比较myid
,此时server2
的myid
最大,于是更新自己的投票为(2,0),然后重新投票,对于server2而言,无需更新自己的投票,只是再次向集群中所有机器发出上一次投票信息即可
-
-
统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于
server1、server2
而言,都统计出集群中已经有两台机器接受了(2,0)的投票信息,此时便认为已经选举出了leader
-
改变服务器状态。一旦确定了
leader
,每个服务器就会更新自己的状态,如果是follower
,那么就变更为following
,如果是leader
,就变更为leading
举例:如果我们有三个节点的集群,1,2,3,启动 1 和 2 后,2 一定会是 leader
,3 再加入不会进行选举,而是直接成为follower
—— 仔细观察 一台zk
无法集群,没有leader
服务器运行时期选举(这个与原子广播很重要)
在zookeeper
运行期间,leader
与非leader
服务器各司其职,即使当有非leader
服务器宕机或者新加入,此时也不会影响leader
,但是一旦leader
服务器挂了,那么整个集群将暂停对外服务,进入新一轮leader
选举,其过程和启动时期的leader
选举过程基本一致
假设正在运行的有server1
、server2
、server3
三台服务器,当前leader
是server2
,若某一时刻leader
挂了,此时便开始Leader
选举。选举过程如下
-
变更状态。
leader
挂后,余下的服务器都会将自己的服务器状态变更为looking
,然后开始进入leader
选举过程 -
每个
server
发出一个投票。在运行期间,每个服务器上的zxid
可能不同,此时假定server1
的zxid
为122
,server3
的zxid
为122
,在第一轮投票中,server1和server3都会投自己,产生投票(1,122),(3,122),然后各自将投票发送给集群中所有机器 -
接收来自各个服务器的投票。与启动时过程相同
-
处理投票。与启动时过程相同,此时,
server3
将会成为leader
-
统计投票。与启动时过程相同
-
改变服务器的状态。与启动时过程相同