服务器状态
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
统计投票。与启动时过程相同
改变服务器的状态。与启动时过程相同
原文:https://www.cnblogs.com/lemon-flm/p/14606530.html