浅谈Zookeeper集群选举Leader节点源码

这篇具有很好参考价值的文章主要介绍了浅谈Zookeeper集群选举Leader节点源码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

写在前面:

zookeeper源码比较复杂,本文讲解的重点为各个zookeeper服务节点之间的state选举。至于各个节点之间的数据同步,不在文本的侧重讲解范围内。

在没有对zookeeper组件有一个整体架构认识的基础上,不建议直接死磕细节。本文写作的目的也是基于此,阅读本文,希望读者能够对zookeeper集群架构有一个简单的认识。

本文附有整体架构的执行流程图,请一定要跟着代码多走几遍。本文的二-六节会对该流程中的关键点进行讲解






一、前提共识

1、了解zookeeper集群搭建

不了解如何搭建集群的可以参考网上别人的文章:Zookeeper集群搭建及使用

本文需要了解集群相关的配置为zoo.cfg文件的节点配置信息:

server.1=第一台服务器的主机名:2881:3881
server.2=第二台服务器的主机名:2882:3882
server.3=第三台服务器的主机名:2883:3882

这里针对每一个zookeeper服务,分别含有288x和388x两个端口。第一个端口用来同步节点之间的数据,第二个端口用来进行节点的state选举(对应代码为ServerState枚举类)

在源码中会new很多的Socket通信,一定要区分开不同端口的实例化对象。



2、入口为QuorumPeerMain.main方法

至于为什么直接是这个方法,可以查看对应的脚本文件。大部分使用脚本文件进行执行的,都是同样的方式(如tomcat)。

如果左边的sh文件不方便看,可以看右边的sh文件(毕竟逻辑更简单)

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket



3、整体流程图(重点)

一定要一定要,跟着流程图多走几遍

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket



4、需要有Socket网络编程、多线程相关基础

源代码中出现大量的Socket通信,也包含创建大量的多线程代码。不了解这两部分知识的小伙伴,看起来可能比较吃力






二、基础流程

1、入口main

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket



2、流程图

这部分比较简单,主要完成的几件事情可以总结为:

  1. 解析配置文件的配置信息
  2. 初始化zookeeper用于接收客户端命令(create、delete、get)的服务端,可选择Netty或者NIO方式,并且完成对应的服务端的启动
  3. 设置对应的集群leader选举的选举类型(设置为3,未来会在Switch中用到该值)
  4. 启动一个内嵌的jetty服务器,用来查看未来服务端的信息
  5. 初始化对应的多级队列架构
  6. 进行具体的集群leader节点的选举

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket






三、多级队列构建流程

1、多级队列架构讲解

看不懂这个图的,建议先把源码跟一遍,再回头看

首先看一下多级队列架构图

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket



我们可以将该多级队列可以分为两层:

第一层:应用层,可以理解为我们上层api队列

代表队列:sendqueue、recvqueue

对应线程名称:WorkerSender、WorkerReceiver


第二层:传输层,可以理解为后台传送数据的队列

代表队列:recvQueue、queueSendMap(map的value为传输层队列)、senderWorkerMap(map的value为SendWorker线程)

对应线程名称:SendWorker、RecvWorker


牢记上面这几个队列、map、线程的名字。否则代码你会看不清楚




处理多级队列流程大致可以描述为

1、首先会初始化对应的ServerSocket端,同时进行accept阻塞监听数据;

2、如果处理leader节点对应的端口接收到数据,那么就会处理该请求。刚开始初始化的时候是不会有数据的,毕竟Socket客户端都还没有开始建立,在第10步才建立的;

3、然后会对信息中的sid进行判断,然后剔除掉不需要的socket连接。因为socket通信是全体连接都发一遍,zk的判定规则为只能由sid大的发给sid小的,所以如果小的发送给了大的,就会关闭连接,并且开启一个反向连接;

4、如果是小的发送给大的,此时就会初始化出我们多级队列的第二级队列传输层队列,以及对应的SendWorker线程任务。然后把这个SendWorker任务放入senderWorkerMap中,未来可以直接取出来直接使用;

5、这里的SendWorker任务,就是真实的把数据通过Socket请求把数据发送给远端的逻辑;

6、接下来开始处理第一级队列应用层队列;

7、即初始化sendqueue和recvqueue这两个上层传输队列;

8、然后就是初始化对应的Socket客户端。当然在初始化客户端的前提是,我们有业务数据放到了第一级的队列中,即第7步中的队列中要有数据;

9、上层业务队列有数据以后,会将业务数据封装为一个ByteBuffer类型的requestBuffer对象,然后把数据直接发送给传输层的队列(queueSendMap中对应sid的value对应的队列);

10、输入发送后,初始化对应的Socket客户端连接,这样就能够把数据发送出去,与此同时,第2步的accept也能接收到数据,最终形成两级队列工作工作的闭环。


第10步使用Socket发送的数据,会与第2步的ServerSocket连接打通。一定要明确这是在集群环境下的通信,明白这一步,很重要



与之对应的recvqueue只是逻辑反一下,首先RecvWorker线程执行会获取到数据,发送给一级队列应用层队列recvqueue,一级队列对应的WQorkRecevier线程任务,就会执行对应的逻辑,然后处理数据。



2、入口startLeaderElection

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket
zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket



3、初始化二级队列

1)Listener方法内部

  • 绑定服务端信息
  • accept数据
  • 处理数据
zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

2)根据接收到的信息的sid情况进行不同的逻辑

  • 如果是自己的就发给自己
  • 如果不是自己,并且满足zk的sid由大机器发送给小机器的规则,则开启对应的两个用于处理二级队列(传输层队列)的线程任务
zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

3)以SendWorker线程任务为例

  • queueSendMap中获取对应sid的队列,然后获取应用层队列中的数据,并将其发送给传输层队列
  • 最终调用send方法,完成数据的传输
zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket
zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket



4、初始化一级队列

1)完成一级队列的初始化

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

2)完成一级队列对应的线程任务的初始化

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

3)调用对应线程的run方法,然后调用process方法处理数据

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

4)把数据发送给运输层队列

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

5)建立socket客户端连接

  • 首先调用内部的connetOne方法
  • 然后把数据封装为一个任务,放进线程池
  • 在线程任务中会初始化对应的Socket客户端连接
  • 封装数据写入到输出流。此时二级队列初始化出来的阻塞的ServerSocket就能够开始向下执行,处理接收到的数据,形成闭环
zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

将线程任务放进线程池代码

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

该任务会初始化对应的客户端

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

封装对应的输出数据,并完成发送

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket





四、LOOKING节点选举流程

1、节点选举基础流程讲解

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

流程选举大致流程可以描述为:

1、第一轮选票:myid为1和myid为2的两台机器,分别把自己的选票发送出去(vote形式),两台机器会分别对自己收到的选票和自己的选票进行比较。会根据指定的判断规则进行选择(粗略可以理解为,是周期、zxid和机器id几个要素中大的);

2、myid为1的机器收到(2,0),会和自己的选票(1,0)进行比较,发现还是(2,0)大,所以最终它会把(2,0)返回回去。此轮中,两台机器发送的选票都没有超过半数(一共3台服务,配置文件中能获取);

3、第二轮选票:myid为1和myid为2的两台机器,再次发送自己的选票信息。此时由于myid为1的这台机器发送的就是上一轮接收到的(2,0)选票。那么在第二轮投票时myid为1的机器就会投出(2,0),与此同时,myid为2的机器投出的选票也是(2,0);

4、此轮中投出的选票(2,0)超过了半数(2/3)。最终myid为2的这台机器被选为了leader节点;

5、当myid为3的节点进来的时候,虽然它的(3,0)大于(2,0),但是其周期比较小(参与投票的周期次数),所以myid为2的机器依然还是leader节点。



2、LOOKING节点流程

每一个节点进来以后的第一步逻辑就是这个位置

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket



3、投票PK逻辑源码

1)首先会把自己的投票信息发送出去,然后再获取自己的recvqueue队列(传输层队列,具体逻辑在多级队列章节进行过讲解)中的投票信息,只要满足条件,就可以不断的去获取队列中的数据

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

2)紧接着对接收到的选票进行逻辑判断。根据其不同的state走不同的逻辑,最终根据判断逻辑再次把消息发送出去

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

3)这是很重要的一个判断规则,根据指定的要素进行判定两个选票的规则

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

4)会调用该方法,最终走到其半数判定的条件。最终返回选择出来的leader节点,即endVote对象,如果没有选择到leader节点,则返回null

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket
zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket



4、其余节点

LOOKING节点的流程为主要逻辑,在第一轮的while循环过后,就能够明确每种节点对应的类型是什么,第二次while循环的时候,就会走到对应的节点方法中去。详细的执行逻辑可请参考开头的那张流程图

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket





五、Zookeeper之间数据同步

这里就回到了第一节中的,第一个共识。即配置集群的时候是有两个端口,最后面的端口,是用于集群节点的选举,倒数第二个端口则是用于同步Zookeeper节点之间的数据。

既然出现了新的端口通信,那么就会初始化新的服务端

1、初始化LEADING节点

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

2、初始化新端口的服务端

这里就会根据新的配置,初始化新的服务端,用来接收zookeeper客户端之间的命令

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket





六、LEADING节点挂之后流程

1、LEADING节点会不断发送PING命令

1)如果是leader节点则会走这段逻辑

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

2)在一个while死循环内部,会周期性的给learner发送ping数据

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

3)封装对应的PING数据包

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket



2、FOLLOWING节点不断接收命令

1)只要机器还运行着,就会轮循该方法,节点是FOLLOWING的机器就会调用follwLeader方法

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket

2)该方法中会调用readPacket方法,去接收数据。后面的processPacket方法会对接受到的数据进行处理。在这过程中就会出现获取不到数据,然后抛异常。那么就会跳转到上一步,在updateServerState()方法中,就会根据逻辑,把自己的FOLLWING节点设置为LOOKING节点,继而触发后续的再次选举流程

zookeeper怎么选取的主节点,ZooKeeper,zookeeper,网络,分布式,java,socket




至此Zookeeper中Leader节点选取的流程就告一段落。开头那张整体的流程图,一定要多跟着源码多走几遍。文章来源地址https://www.toymoban.com/news/detail-724213.html

到了这里,关于浅谈Zookeeper集群选举Leader节点源码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • zookeeper4==zookeeper源码阅读,FOLLOWER收到了需要LEADER执行的命令后各节点会执行什么

    上面已经阅读并观察了节点确定自己的身份后会做些什么,大致就是比对双方信息然后完成同步。 本篇阅读, FOLLOWER收到了需要LEADER执行的命令后,怎么同步给LEADER的,并且LEADER会执行什么操作。 源码启动zkCli用于测试 将原本的代码拷贝一份用IDEA打开后,找到org.apache.zook

    2024年02月03日
    浏览(26)
  • Kafka 和 Zookeeper 的 Leader 和 Follower 区别(选举&数据同步)

    》Client与Server通过NIO通信 》全局串行化所有的写操作 》保证同一客户端的指令被FIFO执行 》保证消息通知的FIFO (2)kafka 不同,只有leader 负责读写,follower只负责备份,如果leader宕机的话,Kafaka动态维护了一个同步状态的副本的集合(a set of in-sync replicas),简称ISR,ISR中有f+1个节

    2024年04月10日
    浏览(54)
  • 一文通吃:从 ZooKeeper 一致性,Leader选举讲到 ZAB 协议与 PAXOS 算法(上)

    本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注\\\"慕课网\\\"或慕课网公众号! 作者:大能 | 慕课网讲师 本文将从ZooKeeper集群如何保证一致性,讲到zookeeper保证数据一致性的协议,然后展开讲Zookeeper集群Leader选举,包括集群三种节点的类型,ZAB协议中

    2024年02月07日
    浏览(42)
  • ZooKeeper的应用场景(集群管理、Master选举)

    随着分布式系统规模的日益扩大,集群中的机器规模也随之变大,因此,如何更好地进行集群管理也显得越来越重要了。 所谓集群管理,包括集群监控与集群控制两大块,前者侧重对集群运行时状态的收集,后者则是对集群进行操作与控制。在日常开发和运维过程中,我们经

    2024年02月12日
    浏览(24)
  • zookeeper选举流程源码分析

    zookeeper选举流程源码分析 选举的代码主要是在 QuorumPeer.java 这个类中。 它有一个内部枚举类,用来表示当前节点的状态。 LOOKING: 当前节点在选举过程中 FOLLOWING:当前节点是从节点 LEADING: 当前节点是主节点 OBSERVING: 当前节点是观察者状态,这种状态的节点不参与选举的投

    2024年02月11日
    浏览(26)
  • 如何保证分布式系统中服务的高可用性:应对 ZooKeeper Leader 节点故障的注册处理策略

    作者:zhaokk 在现代分布式系统中,高可用性是一个至关重要的。分布式系统中的各个组件需要保证在各种异常情况下仍然能够正常工作,确保系统的稳定性和可靠性。ZooKeeper(以下简称为zk)作为一种常用的分布式协调服务,为分布式系统中的各种任务提供了基础支持

    2024年02月11日
    浏览(50)
  • 使用Zookeeper对集群节点进行管理

    Zookeeper是Hadoop生态系统中分布式的服务管理框架,负责存储和管理集群中的公共数据如配置信息等,并且对节点进行注册和通知管理。它具有如下几个特点: 集群由一个领导者(Leader),多个跟随者(Follower)组成 集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。

    2024年02月06日
    浏览(27)
  • Zookeeper集群单节点启动成功但未同步其他节点数据

    首先排查节点启动是否正常: 在zookeeper的bin目录下执行:sh zkServer.sh status 判断当前节点数据leader 还是follower  节点都启动正常,但某一个zookeeper集群节点(下面简称“异常节点”)不同步其他节点数据,解决步骤: 1、查看异常节点的配置文件(**/zookeeper/conf/zoo.cfg) 2、找到

    2024年02月11日
    浏览(26)
  • Zookeeper 集群中节点之间数据是如何同步的

    1.首先集群启动时,会先进行领导者选举,确定哪个节点是 Leader ,哪些节点是 Follower 和 Observer 2.然后 Leader 会和其他节点进行数据同步,采用发送快照和发送 Diff 日志的方式 3.集群在工作过程中,所有的写请求都会交给 Leader 节点来进行处理,从节点只能处理读请求 4.

    2024年02月09日
    浏览(29)
  • Kafka学习--3、Kafka Broker、节点服役和退役、Kafka 副本、Leader 选举流程、故障处理

    1.1 Kafka Broker工作流程 1.1.1 Zookeeper储存的Kafka信息 (1)启动Zookeeper集群、再启动Kafka集群,然后启动Zookeeper客户端 (2)通过ls命令可以查看kafka相关信息。 1.1.2 Kafka Broker总体工作流程 1、模拟Kafka上下线,Zookeeper中数据变化 (1)查看/kafka/brokers/ids 路径上的节点。 (2)查看

    2024年02月10日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包