• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

zookeeper原理篇Zookeeper选举过程分析

android 搞代码 3年前 (2022-03-01) 24次浏览 已收录 0个评论

选举过程概述

通过后面的zookeeper相干的文章,咱们也对zookeeper有肯定的理解,晓得在zookeeper中存在三种服务器角色,别离是Leader,Follower以及Observer,其中Observer仅仅作为一个监控协调者的作用,并不参加zookeeper对外提供服务以及zookeeper的选举,而zookeeper的选举咱们从后面的内容也晓得,总共能够分为两种,第一种是当整个zookeeper的集群启动后,进行的选举过程,第二种则是在zookeeper运行期间,当呈现Leader解体的过程时,zookeeper进行的选举操作。接下来咱们先从启动的时候触发的选举开始学习

服务端启动时选举过程

咱们在搭建zookeeper的时候往往会有一个配置文件,外面寄存一个myid,用来标示集群内不同客户端的机器编号,当至多两台含有myid的机器启动后,就开始进入了zookeeper的集群选举流程

1.每个server发动一个投票

因为以后是刚启动状态,因而每一个服务实例都会默认把本人作为Leader服务器来发动投票,而每一个投票中蕴含了最根本的选举所须要的元素,例如myid和ZXID,咱们将这两个依照选票的形式示意,例如myid为1,ZXID为0,咱们将会示意为(1,0),因为每台服务端实例优先都是依照本人是Leader发动投票,那么server1默认生成的选票就是(1,0),server2的选票则是(2,0),以此类推

2.承受到其余服务端实例发来的选票

没台服务端实例都会收到其余服务端实例发来的选票信息,当收到选票后,就会开始校验解决选票的流程

3.校验解决选票

其余服务实例发来的选票,要通过一系列验证,比方是不是本轮投票的选票,是否来自于Looking状态的实例发来的选票,通过校验后,就会和以后实例的选票信息进行pk比拟,比拟的规定大抵如下:

①优先比拟ZXID,ZXID不一样的时候,较大的那个选票所在的服务实例作为Leader

②如果两个选票的ZXID雷同的话,那么就会比拟myid,默认为myid较大的服务实例作为Leader

依据这个规定,咱们来看看当server1收到server2的选票后,比拟的流程是怎么的,首先两个选票都是第一轮投票选举,所以zxid都是0,接着就要开始比拟myid了,server1的myid是1,而server2的myid是2,大于本身的myid,那么server2就应该是Leader,因而server1会更新本人的选票为(2,0),而后下次发送的时候就是发送新的选票信息进来

4.统计每一次选票

每一次投票当前,都会统计所有的投票,判断是否有过半的实例承受到了雷同的选票信息,对与以后server1和server2来说,必须这两个实例的选票都一样才能够算是实现了选举流程,而如果是复数的实例的话,只须要达到(实例数 + 1) / 2的服务端实例承受到一样的选票即可。而通过下面的流程当前,只有server1比拟完选票,也收回了(2,0)的选票信息,即可实现选举

5.同步服务端实例状态

一旦选举实现,选出了Leader实例,每个服务实例都会更新本身的状态,如果是Follower,就会变为FOLLOWER,如果是Leader则会变成LEADING状态。

服务端运行期间进行的选举

除了启动zookeeper集群的时候,个别状况下Leader会始终作为集群中的Leader,即便集群中的Follower挂了或者是新机器实例退出集群中,也不会影响Leader。然而一旦Leader无奈响应或者是宕机了,Zookeeper集群将无奈对外进行服务,而是进行新一轮的Leader选举,而这个选举的过程与初始化启动集群的选举过程大体上是差不多的,然而有区别的是这个时候每个机器将要从本身的运行状态切换到选举状态

1.更新本身状态

当Leader实例挂了当前,剩下的所有Follower实例都会将本身的服务状态变更为LOOKING,而后进行Leader选举流程

2.一样的选举流程

Leader选举的大体流程都是一样的,这里将不再赘述,当实现选举当前,每个服务端实例依照本身的角色,将本身的状态批改为对应的角色状态,这个时候选举实现,Zookeeper集群复原对外提供服务。

Zookeeper的选举算法

zookeeper的选举的大略流程咱们晓得了,然而咱们都晓得,选举的过程是基于算法的,zookeeper的选举算法有哪些呢?在zookeeper中,提供了三种Leader选举的算法,别离是LeaderElectionUDP版本的FastLeaderElection以及TCP版本的FastLeaderElection三种选举算法。而选举算法,则是能够在zoo.cfg配置文件中的electionAlg属性来指定,这三种选举算法别离对应值为0-3,其中0为LeaderElection算法,应用的是UDP协定实现,1代表UDP版本的FastLeaderElection算法,这种算法是非受权模式,2代表的也是UDP版本的FastLeaderElection算法,不过这种应用的是受权模式,3代表是TCP协定实现的FastLeaderElection算法。

不过须要留神的是,从Zookeeper3.4.X版本开始,Zookeeper官网曾经废除了UDP协定实现的0-2这三种Leader选举算法,仅仅保留了3这一种TCP协定实现的FastLeaderElection算法,这也是为什么下面咱们介绍选举的大抵流程中不针对每一种选举算法进行剖析的起因。

Leader选举的细节

学习了选举的大略流程当前,咱们发现整体流程和算法的设计不难,然而具体如何解决常见的问题的?这个时候咱们须要深刻细节来学习,首先Zookeeper为了解决不同状况,设计了多个服务端的状态,这个状态的定义在org .apache .
zookeeper . server.quorum .QuorumPeer. ServerState 类中,别离如下:

LOOKING:寻找Leader服务的状态,处于以后状态后,将会进行Leader选举流程

FOLLOWING:代表以后服务端处于跟随者状态,表明是Follower服务

LEADING:代表以后服务端处于领导者状态,表明是Leader服务

OBSERVING:观察者状态,表明是Observer服务

后面咱们也提到过,每次收回选票后,选票中蕴含了根本的元素,即ZXID和myid,而这个选票的定义在 apache.zookeeper.server.quorum.Vote类,代码如下:

final private int version;
final private long id;
final private long zxid;
final private long electionEpoch;
final private long peerEpoch;

咱们把常见的几个属性进行阐明,如下:

属性 阐明
id 被选举的SID
zxid 以后Leader的事物ID
electionEpoch 逻辑时钟,解析进去的,以后处于第几轮选举投票,每次进入新一轮投票后,都会加1
peerEpoch 以后被选举的Leader的epoch
state 以后服务所处于的状态

学习了这些后,咱们来看看选举的通信,后面咱们有聊过CilentCnxn是Zookeeper客户端中用于解决I/O网络通信的管理器,而对应的Zookeeper的server中也有一个类–QuorumCnxManager类来承受和解决Leader选举中的通信,而整个过程能够划分几个局部,大抵如下:

音讯队列解决音讯

QuorumCnxManager类中保护了很多队列,用于保留承受到的、期待发送的音讯,还定义了音讯发送器等,除了承受队列以外,其余的队列都是依照SID分组的汇合。其中常见的队列和属性定义如下:

  • recvQueue:音讯承受队列,用于寄存承受来的所有的音讯
  • queueSendMap:音讯待发送队列,用于保留期待发送的音讯汇合,定义为一个Map,依照SID分组设置为key,并且每一个SID对应的都保护了一个队列,保障收发音讯互不影响
  • senderWorkMap:发送器汇合,每一个senderWork发送器都对应一个近程连贯的zookeeper,负责发送音讯,在senderWorkMap外部,也是依照SID分组进行保护的。
  • lasteMessageSent:最近发送的音讯,在这个汇合中,会为每一个SID保护一个最新发送的音讯

建设连贯

为了能彼此之间通信,zookeeper集群中的实例须要两两建设连贯,QuorumCnxManager类在启动的时候会床架一个ServerSokect来监听Leader选举的通信端口,在承受到申请的时候,会调用receiveConnection函数来解决,然而为了防止反复的创立TCP连贯,Zookeeper建设了一个规定,只容许SID大的机器往SID小的机器建设连贯,当连贯连理后,依据近程服务实例的SID创立对应的senderWorker和对应的音讯接收器RecvWorker

音讯承受和发送

当音讯接收器不停的收到音讯后,会将其保留在recvQueue队列中,音讯发送比较简单,因为每一个SID都有一个保护的独立的SendWorker,只须要不停的从queueSendMap获取要发送的数据进行发送即可,发送结束后,会将刚刚发送的音讯存入lasteMessageSent中,然而须要留神的是,当发现带发送音讯的队列是空的时候,就会从lasteMessageSent中获取刚刚发送的音讯,而后再次作为音讯发送进来,这么设计的起因是为了避免接受方没有收到音讯,或者是收到音讯后挂了,导致音讯没解决完,因为Zookeeper本身对反复音讯有解决机制,因而反复发送音讯,能够保障能正确处理音讯

FastLeaderElection算法

zookeeper的选举网络IO模块咱们大抵晓得了,接下来咱们来看看FastLeaderElection选举算法的外围算法实现,流程图如下:

[外链图片转存失败,源站可能有防盗链机制,倡议将图片保留下来间接上传(img-cYWirecg-1634906173442)(assets/1587291882174.png)]

1.自增选举次数

FastLeaderElection的实现中,有一个logicalclock属性,用于标识以后选举的次数,zookeeper要求每次发动选举的时候必须是在同一次选举周期中,因而在每一次选举之前,都会触发logicalclock的自增,达到以后的选举周期

2.初始化选票

后面咱们曾经晓得了选票类的定义在apache.zookeeper.server.quorum.Vote,初始化阶段的时候,每台服务器都会推举本人为Leader,因而都会先初始化一个以本人为主的选票

3.将初始化的选票发送

初始化完选票当前,会将本人的选票信息存入sendQueue队列中,而后用对应每一个SIDworkerSender负责发送进来

4.承受内部投票信息

初始化阶段,除了发送本身的选票信息以外,还会承受来自其余的服务实例发来的选票信息,这些信息存入recvQueue队列中,如果发现无奈获取到其余选票信息,就会确认以后服务实例是否和其余的服务实例放弃着连贯,如果发现连贯断开或者是没有连贯,则会再次建设连贯,当然这里建设连贯仍然是比照以后服务SID的服务发动连贯,防止出现反复创立连贯

5.判断选举次数

当发送完初始化选票后,就会开始解决承受来的其余服务实例的选票信息,首先判断承受到的内部投票的选举次数是否大于以后的选票

  • 如果大于以后服务的选票中的选举次数,那么则会更新以后服务的logicalclock,并且清空所有收到的选票,再次拿选票和内部投票进行选票的比拟,确定是否真的要更改本身的选票,而后从新发送选票信息。
  • 如果内部选票的选举次数小于以后服务实例的选举次数,那么间接忽视掉这个选票信息,并且持续发送本身的选票进来
  • 如果内部选票和本身服务实例的选举次数统一,那么就须要进入选票之间的比拟操作

6.选票的比拟

选票比拟就是整个选举算法的外围逻辑,实现在FastLeaderElection#totalOrderPredicate办法,选票比拟次要是为了确定以后服务实例的选票信息是否须要更改当前再次发送新的选票信息,因而会依照选举次数、ZXID和SID来比拟:

  • 如果内部投票的选举次数大于以后服务实例的选举次数,就须要投票变更
  • 如果选举轮次统一,那么比拟ZXID,如果内部选票的ZXID比拟大,须要扭转本身服务实例的选票信息
  • 如果ZXID统一,那么就须要比拟SID,内部投票的SID较大,本身服务实例的选票信息须要扭转

7.更改选票信息,再次发送

通过选票比拟当前,如果发现须要更改本身的选票信息,会先批改本身的选票信息,而后再次依照新的选票信息发送进来

8.选票统计归档

每个服务实例在发送和承受过程中,无论是否清空还是忽视局部选票,都会把每一个选票的信息存入recvSet中进行归档统计,外部存储依照SID辨别选票信息,而后进行统计计算,只有发现超过半数以上的服务实例进行了投票,就能够进行发送选票信息,完结选举,否则持续反复下面的发送和承受选票过程

9.选举Leader当前,进行服务实例的状态变更

当进行了投票当前,统计进去最终的Leader服务实例当前,就开始批改每个服务实例的状态,具体的逻辑是查看选出来的Leader是不是本人,如果是,则将本身的状态批改为LEADING,如果不是,则依据状况批改本身的状态为FOLLOWING或者是OBSERVING

至此,FastLeaderElection算法的外围流程实现,然而咱们须要留神的是,后面4-8的步骤,可能会通过很屡次,因为每一次选举过程中,即便收到了过半的选票,不肯定就能选出Leader服务,可能须要选举屡次,并且每一次选举投票过程中,会有屡次发送选票的过程,因为每一个服务实例发送选票的周期是随机的,同时还须要留神的一点是,即便选票超过半数了,选出Leader服务实例了,也不是立即完结,而是期待200ms,确保没有失落其余服务的更优的选票


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:zookeeper原理篇Zookeeper选举过程分析

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址