分布式与一致性协议之ZAB协议(六)

ZAB协议

成员发现

成员发现是通过跟随者和领导者交互来完成的,目标是确保大多数节点对领导者的关系没有异议,也就是确立领导者的领导地位。成员发现的实现流程如图所示。
在这里插入图片描述

  • 1.领导者选举结束,节点进入跟随者状态或者领导者状态后,会分别设置ZAB状态为成员发现状态,具体如下:
    1.1 跟随者会调用Follower.followLeader()函数,设置ZAB状态为成员发现状态,如代码所示
self.setZabState(QuorumPeer.ZabState.DISCOVERY);

1.2 领导者会调用Leader.lead()函数,并设置ZAB状态为成员发现状态,如代码所示

self.setZabState(QuorumPeer.ZabState.DISCOVERY);
  • 2.跟随者会主动联系领导者,发送自己已接收的领导者任期编号的最大值(也就是acceptedEpoch)的FOLLOWINFO消息给领导者,如代码所示
// 跟领导者建立网络连接
connectToLeader(leaderServer.addr, leaderServer.hostname);
connectionTime = System.currentTimeMills();
// 向领导者报道,并获取领导者的事务标识符最大值
long newEpochZxid = registerWithLeader(Leader.FOLLOWERINFO);
  • 3.在接收到来自跟随者的FOLLOWINFO消息后,在LearnerHandler.run()函数中,领导者将创建包含自己的事务标识符最大值的LEADINFO消息,并响应给跟随者,如代码所示
// 创建LEADINFO消息
QuorumPacket newEpochPacket =
new QuorumPacket(Leader.LEADERINFO, newLeaderZxid, ver, null);
// 发送LEADINFO消息给跟随者
oa.writeRecord(newEpochPacket, "packet");
  • 4.在接收到来自领导者的LEADINFO消息后,跟随者会基于领导者的任期编号判断领导者是否合法,如果领导者不合法,则发起新的选举,如果领导者合法,则响应ACKEPOCH消息给领导者,如代码所示
// 创建ACKEPOCH消息,包含已提交提案的事务标识符最大值
QuorumPakcet ackNewEpoch =
new QuorumPacket(Leader.ACKEPOCH, lastLoggedZxid, epochBytes, null);
// 响应ACKEPOCH消息给领导者
writePacket(ackNewEpoch, true);
  • 5.跟随者设置ZAB状态为数据同步状态,如代码所示
self.setZabState(QuorumPeer.ZabState.SYNCHRONIZATION);
  • 6.在LearnerHandler.run()函数中(以及Leader.lead()函数),领导者会调用waitForEpochAck()函数来阻塞和等待来自大多数节点的ACKEPOCH消息,如代码所示
ss = new StateSummary(bbepoch.getInt(), ackEpochPacket.getZxid());
learnerMaster.waritForEpochAck(this.getSid(), ss)
  • 7.在接收到来自大多数节点的ACKEPOCH消息后,在Leader.lead()函数中,领导者设置ZAB状态为数据同步状态。
self.setZabState(QuorumPeer.ZabState.SYNCHRONIZATION);

这样,ZooKeeper就实现了成员发现,且各节点就领导者的领导关系达成了共识。当跟随者和领导者设置ZAB状态为数据同步状态后,它们就进入了数据同步阶段。那么ZooKeeper中的数据同步是如何实现的呢?

数据同步

数据同步也是通过跟随者和领导者交互来完成的。目标是确保跟随者节点上的数据与领导者节点上的数据一直。数据同步的实现流程如图所示。
在这里插入图片描述

  • 1.在LearnerHandler.run()函数中,领导者调用syncFollower()函数,根据跟随者的事务标识符的最大值判断用哪种方式处理不一致数据,并把已提交提案和未提交提案都同步给跟随者,如代码所示
peerLastZxid = ss.getLastZxid();
boolean needSnap = syncFollower(peerLastZxid, learnerMaster);

在这里,你需要了解领导者向跟随者同步数据的3种方式(TRUNC、DIFF、SNAP),它们分别代表什么含义呢?要想了解这部分内容,首先要了解一下syncFollower()中3个关键变量的含义。
1.peerLastZxid:跟随者节点上提案的事务标识符欸度最大值
2.maxCommittedLog、minCommittedLog:领导者节点内存队列中已提交提案的事务标识符的最大值和最小值。需要注意的是,maxCommittedLog、minCommittedLog与ZooKeeper的设计有关。在ZooKeeper中,为了更高效地将提案复制到跟随者,领导者会将一定数量(默认值为500)的已提交提案放在内存队列里,而maxCommittedLog、minCommittedLog分别标识的是内存队列中已提交提案的事务标识符最大值和最小值。

说完3个关键变量,再来说说3种同步方式。
1.TRUNC:当peerLastZxid大于maxCommittedLog时,领导者会通知跟随者丢弃超出的那部分提案。比如,如果跟随者的peerLastZxid为11,领导者的maxCommittedLog为10,那么领导者将通知跟随者丢弃事务标识符值为11的提案
2.DIFF:当peerLastZxid小于maxCommittedLog但大于minCommittedLog时,领导者会向跟随者同步缺失的已提交的提案,比如,如果跟随者的peerLastZxid为9,领导者的maxCommittedLog为10,minCommittedLog为9,那么领导者将同步事务标识符值为10的提案给跟随者
3.SNAP:当peerLastZxid小于minCommittedLog时,也就是说,跟随者缺失的提案比较多,那么领导者会同步快照数据给跟随者,并直接覆盖跟随者本地的数据。
在这里,补充一下,领导者先就已提交提案和跟随者达成一致,然后调用learnerMaster.startForwarding()将未提交提案(如果有的话)也缓存发送队列(queuedPackets),并最终复制给跟随者。也就是说,领导者是以自己的数据为准,实现各节点数据副本的一致的。
需要注意的是,在syncFollower()种,领导者只是将需要发送的差异数据缓存在发送队列,还没有实际发送

  • 2.在LearnerHandler.run()函数种,领导者创建NEWLEADER消息并缓存在发送队列种,如代码所示:
// 创建NEWLEADER消息
QuorumPacket newLeaderQP =
new QuorumPacket(Leader.NEWLEADER, newLeaderZxid,learnerMaster.getQuorumVerifierBytes(), null);
// 缓存NEWLEADER消息到发送队列中
queuedPackets.add(newLeaderQP);
  • 3.在LearnerHandler.run()函数中,领导者调用startSendingPackets()函数启动一个新线程,并将缓存的数据发送给跟随者,如代码所示
// 发送缓存队列中的数据
startSendingPackets();
  • 4.跟随者调用syncWithLeader()函数,处理来自领导者的数据同步,如代码所示
// 处理数据同步
syncWithLEader(newEpochZxid);
  • 5.在syncWithLeader()函数中,跟随者在接收到来自领导者的NEWLEADER消息后,返回确认响应给领导者,如代码所示
writePacket(new QuorumPacket(Leader.ACK, newLeaderZxid, null, null), true);
  • 6.在LearnerHandler.run()函数(以及Leader.lead()函数)中,领导者等待来自大多数节点的NEWLEADER消息的响应,如代码所示
learnerMaster.waitForNewLeaderAck(getSid(), qp.getZxid());
  • 7.当接收到来自大多数节点的NEWLEADER消息的响应时,在Leader.lead()函数中,领导者设置ZAB状态为广播状态,如代码所示
self.setZabState(QuorumPeer.ZabState.BROADCAST);

同时,在LearnerHandler.run()中发送UPTODATE消息给所有跟随者,通知它们数据同步已经完成了,如代码所示

queuedPackets.add(new QuorumPacket(Leader.UPTODATE, -1, null, null));
  • 8.跟随者在接收到UPTODATE消息后会直到数据不一致已修复,可以处理写请求了,同时设置ZAB状态为广播状态
// 数据同步完成后,跟随者就可以正常处理来自领导者的广播消息了,同时设置ZAB状态为广播状态
self.setZabState(QuorumPeer.ZabState.BROADCAST);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/8031.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速搭建linux虚拟机环境

1、虚拟机资源 VMwareWorkstation:Download VMware Workstation Pro virtualbox:Oracle VM VirtualBox 2、虚拟机系统资源 链接:系统资源链接 提取码:0gat 说明:此处的系统资源是采用VMwareWorkstation 虚拟机进…

简单两步将Lllama、Qwen等开源大模型安装到自己的电脑上

现在已经有非常多优秀的开源大语言模型了,比如Command R、Mistral、Qwen、MiniMax、Baichuan、Phi3等,其中Lllama3和Qwen等已经和GPT4的性能比较接近了。 如果能把这些免费的开源大模型部署到本地电脑或手机上,可以完全自由的使用&#xff0…

深入探索van Emde Boas树:原理、操作与C语言实现

van Emde Boas (vEB) 树是一种高效的数据结构,用于处理整数集合。它是由荷兰计算机科学家Jan van Emde Boas在1977年提出的。vEB树在处理整数集合的查找、插入、删除和迭代操作时,能够以接近最优的时间复杂度运行。vEB树特别适合于那些元素数量在某个较小…

【边东随笔】(2) “顶级掠食者” 的生存智慧:信心 | 狠心 | 耐心

(北美鳄龟, Alligator Snapper) "优雅,且致命。" 非常谨慎,在水域中会先找到躲避将自身安置于有利地形。浮出水面换气,水体稍有异动就会退回水中,优秀掠食者对自身优势牢牢的把握( 信…

hadoop学习---基于Hive的教育平台数据仓库分析案例(二)

衔接第一部分,第一部分请点击:基于Hive的教育平台数据仓库分析案例(一) 意向用户模块(全量分析): 需求指标: 需求一: 计期内,新增意向客户(包含自己录入的意…

kraken2 最新版安装,极简模式

kraken2 git clone https://github.com/DerrickWood/kraken2.gitcd kraken2./install_kraken2.sh /opt/krakenvim .bashrc ---------------- # Kraken export PATH"/opt/kraken:$PATH" ----------------source .bashrc Note: 不晓得是不是我设置了清华源&#xff0c…

下载源代码并交叉编译riscv FreeBSD系统和内核

RISCV系统曾经让人神秘到无法接触,交叉编译更是只有耳闻,现在随着RISCV的普及,它们神秘的面纱已经被慢慢揭开。 交叉编译作为RISCV系统中的一个重要环节,也随着RISCV的普及而变得更加容易理解和操作。交叉编译允许开发者在一个平…

LeetCode算法题:8.字符串转换整数 (atoi)

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C 中的 atoi 函数)。 函数 myAtoi(string s) 的算法如下: 读入字符串并丢弃无用的前导空格检查下一个字符(假设还未到字符末…

WordPress原创插件:当日24小时发布文章标题变红

WordPress原创插件&#xff1a;当日24小时发布文章标题变红 <?php// 添加自定义样式 function title_red_plugin_styles() {$current_time time();$post_time get_the_time(U);$time_difference $current_time - $post_time;if ($time_difference < 86400) {echo&l…

24_Scala集合Map

文章目录 Scala集合Map1.构建Map2.增删改查3.Map的get操作细节 Scala集合Map –默认immutable –概念和Java一致 1.构建Map –创建kv键值对 && kv键值对的表达 –创建immutable map –创建mutable map //1.1 构建一个kv键值对 val kv "a" -> 1 print…

Web3智能物联网:科技连接的未来世界

在当今科技飞速发展的时代&#xff0c;Web3智能物联网正逐渐成为人们关注的焦点。随着区块链技术的不断成熟和普及&#xff0c;以及物联网的普及和应用&#xff0c;Web3智能物联网作为二者的结合&#xff0c;将为未来的数字世界带来革命性的变化。本文将深入探讨Web3智能物联网…

二十、Java的反射机制

1、Java反射机制的概念 所谓反射从程序的运行结果来看也很好理解,即可以通过对象反射求出类的名称。如下: 正常方式:引入需要的“包.类”名称---->通过new实例化----->取得实例化对象。 反射方式:实例化对象---->getClass()方法------>得到完整的“包.类”名…

基于Django框架课堂投票系统的设计与实现

基于Django框架课堂投票系统的设计与实现 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 学生角色功能实现 注册登录界面 此处输入账号并设置登录密码&#xff0c;填写用户名、性别、生源地等相关信息…

视频断点上传

什么是断点续传 通常视频文件都比较大&#xff0c;所以对于媒资系统上传文件的需求要满足大文件的上传要求。http协议本身对上传文件大小没有限制&#xff0c;但是客户的网络环境质量、电脑硬件环境等参差不齐&#xff0c;如果一个大文件快上传完了网断了没有上传完成&#xf…

【busybox记录】【shell指令】tr

目录 内容来源&#xff1a; 【GUN】【tr】指令介绍 【busybox】【tr】指令介绍 【linux】【tr】指令介绍 使用示例&#xff1a; 转换字符 - 默认 转换字符 - 不翻译指定字符数组 此指令目前接触少&#xff0c;用得少&#xff0c;把精力放到其他常用指令上 常用组合指令…

CP AUTOSAR之CANXL Driver详细说明(正在更新中)

本文遵循autosar标准&#xff1a;R22-11 1 简介及功能概述 本规范描述了AUTOSAR 基础软件模块CAN XL 驱动程序的功能、API和配置。   本文档的基础是[1,CiA610-1]和[2,CiA611-1]。假设读者熟悉这些规范。本文档不会再次描述CAN XL 功能。   CAN XL 驱动程序是最低层的一部…

125.两两交换链表中的节点(力扣)

题目描述 代码解决及思路 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), …

一篇迟来的未来展望的博客

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 老师布置的任务&#xff0c;叫写一篇博客&…

04.2.配置应用集

配置应用集 应用集的意思就是&#xff1a;将多个监控项添加到一个应用集里面便于管理。 创建应用集 填写名称并添加 在监控项里面找到对应的自定义监控项更新到应用集里面 选择对应的监控项于应用集

【Sql-02】 求每个省份最新登陆的三条数据

SQL 输出要求数据准备sql查询结果 输出要求 要求输出&#xff0c;userid_1,logtime_1,userid_2,logtime_2,userid_3,logtime_3 数据准备 CREATE TABLE sqltest (province varchar(32) NOT NULL,userid varchar(250) DEFAULT NULL,logtime datetime ) ENGINEInnoDB DEFAULT C…