Zookeeper集群启动过程算法
预启动
数据库
统一由QuorumPeerMain做为启动类服务器
读取zoo.cfg配置文件ide
建立并启动历史文件清理器DatadirCleanupManager学习
判断当前是集群模式仍是单机模式spa
初始化线程
建立ServerCnxnFactory,orm
初始化ServerCnxnFactory,初始化一个线程,做为整个ServerCnxnFactory的主线程而后在初始化NIO服务器server
建立Zookeeper数据管理器FileTxnSnapLog,对象
建立QuorumPeer实例,Quorum是集群模式下特有的对象,是Zookeeper服务器实例的托管者,从集群层面来看QuorumPeer表明了Zookeeper集群中一台服务器,在运行期间它会不断检查当前服务器实例运行的状态。而后根据状况进行Leader选举。
建立内存数据库ZKDatabase
初始化QuorumPeer,这里把一些核心组件注册到QuorumPeer,这些核心组件包括FileTxnSnapLog、ServerCnxnFactory和ZKDatabase,同时Zookeeper还会对QuorumPeer配置一些参数,包括服务器地址列表,选举算法和会话超时时间等。
恢复本地数据库
启动ServerCnxnFactory主线程
Leader选举
交互和数据同步(看红色部分)
建立会话管理器
初始化Zookeeper的请求处理链
注册JMX
在Leader选举完成以后会有一个Leader和其余服务器(Follower和Observer 统称Learner学习者)进行交互,大体流程以下:
Leader服务器启动Follower接收器,LearnerCnxAcceptor,来接收全部非Leader服务器的链接
Leader与每个Learner之间都会有一个LearnerHandler实例对应负载它们之间的消息通讯和数据同步
Learner和Leader创建链接后,Learner向Leader注册,就是发送本身的信息给Leader,包括当前服务器的SID和ZXID
Leader解析Learner发来的注册信息,在过半向Leader注册的服务器中找到最大的epoch,而后加1,用于肯定当前集群的epoch
Leader发送LEADERINFO给Learner
Learner收到LEADERINFO,解析出epoch和ZXID而后给Leader一个反馈
Leader收到Learner响应以后就开始与其进行数据同步
启动Leader和Learner服务器,有过半数完成数据同步就能够启动了。
Leader选举
选举原则就是比计较MYID、ZXID,这里咱们以3台为例,其实2台也能够完成选举,可是一般集群规模最小是3台
服务器启动期间的选举
Server1 myid:1 zxid:0
Server2 myid:2 zxid:0
Server3 myid:3 zxid:0
每一个服务器都会发出一条投票且都是投给本身,以Server1为例(1,0),把这个信息发送到集群中其余服务器上。固然它本身也会收到别人的投票信息
每一个服务器收到其余服务器的投票,先会检查有效性包括检查是不是本轮投票以及是否来自LOOKING状态的服务器发出的
处理投票,首先比较ZXID,值最大的为Leader,若是值同样那么就比较myid,myid最大的为Leader,Server1会收到(1,0)(2,0)(3,0)通过比较本身的myid不是最大的,它会从新投票新的投票(3,0)并重新发到集群中去,对于Server2也同样,对于Server3来讲它不用更新投票信息它比较后本身就是最大的全部再次发出投本身的票就能够。这样每一个机器又会收到2个投票信息,Server1会收到Server二、3发来的(3,0)。
每次投票服务器都会进行投票统计,判断是否有超过半数机器相同的投票信息,对于这三台服务器来讲最终投票结果是(3,0),那么除了Server3以外其余都会收到2张(3,0)的投票,这样在一个3台集群中超过半数投票是投给一个机器的,那么这个机器就是集群的Leader。
一旦肯定了Leader那么就须要设置本身的角色以及改变本身的状态Leader变成LEADING,而Follower就变成FOLLOWING。
服务器运行期间的选举
当集群中的服务器数量发生变化时才会进行从新选举,好比以前的Leader故障或者新加入一台Zookeeper服务器。
咱们假设上面的Leader Server3挂了,而后从新选举
Server1 myid:1 zxid:123
Server2 myid:2 zxid:122
Server3 myid:3 zxid: (宕机)
当集群感知到Leader挂了,那么全部Follower角色的服务器就转变状态从FOLLOWING变成LOOKING
每一个服务器发出投票Server1会发出(1,123)到集群中,Server2会发出(2,122)到集群中,由于第一轮都是投本身。
集群中可用服务器收到投票
投票处理,这里和启动时候使用相同的原则,Server1投票不变由于它的ZXID比Server2的大,因此它再次发一个投本身的票,Server2发现本身的ZXID小因此更新投票信息(1,123)再次发出去
统计投票信息,最终Server1胜出成为Leader
改变服务器状态