zookeeper原理篇-Zookeeper选举过程分析,中软国际java二面华为面试

本文详细描述了Zookeeper中服务端实例间选举Leader的过程,包括接收到选票的校验、比较规则,以及FastLeaderElection算法的运用。重点介绍了选举状态、选票结构和通信机制,展示了选举算法在配置文件中的设定。
摘要由CSDN通过智能技术生成

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类,代码如下:

1.  `finalprivateint version;`

2.  `finalprivatelong id;`

3.  `finalprivatelong zxid;`

4.  `finalprivatelong electionEpoch;`

5.  `finalprivatelong 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选举算法的核心算法实现,流程图如下:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

总结

面试难免让人焦虑不安。经历过的人都懂的。但是如果你提前预测面试官要问你的问题并想出得体的回答方式,就会容易很多。

此外,都说“面试造火箭,工作拧螺丝”,那对于准备面试的朋友,你只需懂一个字:刷!

给我刷刷刷刷,使劲儿刷刷刷刷刷!今天既是来谈面试的,那就必须得来整点面试真题,这不花了我整28天,做了份“Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法等”

image

且除了单纯的刷题,也得需准备一本【JAVA进阶核心知识手册】:JVM、JAVA集合、JAVA多线程并发、JAVA基础、Spring 原理、微服务、Netty与RPC、网络、日志、Zookeeper、Kafka、RabbitMQ、Hbase、MongoDB、Cassandra、设计模式、负载均衡、数据库、一致性算法、JAVA算法、数据结构、加密算法、分布式缓存、Hadoop、Spark、Storm、YARN、机器学习、云计算,用来查漏补缺最好不过。

image

Cassandra、设计模式、负载均衡、数据库、一致性算法、JAVA算法、数据结构、加密算法、分布式缓存、Hadoop、Spark、Storm、YARN、机器学习、云计算,用来查漏补缺最好不过。

[外链图片转存中…(img-SsajKUq4-1712012888123)]

  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值