当前位置: 首页 > news >正文

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

ZAB协议

ZooKeeper是如何选举领导者的。

首先我们来看看ZooKeeper是如何实现成员身份的?
在ZooKeeper中,成员状态是在QuorumPeer.java中实现的,为枚举型变量

public enum ServerState {
LOOKING,
FOLLOWING,
LEADING,
OBSERVING
}

其实,ZooKeeper没有直接定义成员身份,而是用了对应的成员状态来表示,比如,处于FOLLOWING状态的节点为跟随者。如果你想研究相关成员的功能和实现,那么可以把对应的成员状态作为切入点来研究。比如,你想研究领导者的功能实现,可以在代码中搜索LEADING关键字,然后研究相应的上下文逻辑,进而得到自己想要的答案。
如果跟随者将自己的状态从跟随者状态变更为选举状态,就表示跟随者在发起领导者选举,那么在ZooKeeper中,领导者选举是如何实现的呢?
领导者选举是在FastLeaderElection.lookForLeader()中实现的。其核心实现流程如图所示。
在这里插入图片描述

为了更好地理解这个流程,我们来一起走读下核心代码:

  • 1.在集群稳定运行时,处于跟随者状态的节点会调用Follower.followLeader()函数周期性地读数据包和处理数据包,如代码所示
QuorumPacket qp = new QuorumPacket();
while (this.isRunning()) {
//读取数据包
readPacket(qp);
// 处理数据包
processPacket(qp);
}
  • 2.当跟随者检测到连接到领导者的读操作超时时(比如领导者节点故障了),它会抛出异常(Exception),跳出上面的读取数据保和处理数据保的循环,并将节点状态变更为选举状态。如代码所示
public void run() {
case FOLLOWING:
......
finally {
// 关闭跟随者节点
follower.shutdown();
setFollower(null);
// 设置状态为选举状态
updateServerState();
}
break;
......
}
  • 3.当节点处于选举状态时,它将调用makeLEStrategy().lookForLeader()函数(实际对应的函数为FastLeaderElection.lookForLeader())发起领导者选举,如代码所示
setCurrentVote(makeLEStrategy().lookForLeader());
  • 4.在FastLeaderElection.lookForLeader()函数中,节点需要对逻辑时钟(也就是选举的轮次)的值执行加1操作,表示开启一轮新的领导者选举,然后创建投票提案(默认推荐自己为领导者)并通知所有节点,如代码所示
synchronized(this) {
// 对逻辑时钟的值执行加一操作
logicalclock.incrementAndGet();
// 创建投票提案,并默认推荐自己为领导者
updateProposal(getInitId(), getInitLastLoggedZxid(), getPeerEpoch());
}
// 广播投票信息给所有节点
sendNotifications();
  • 5.当节点处于选举状态时,它会周期性地从队列中读取接收到地投票信息,直到选举成功,如代码所示
while((self.getPeerState() == ServerState.LOOKING) && (!stop)) {
// 从队列中读取接收到地投票信息
Notification n = recvqueue.poll(notTimeout, TimeUnit.MILLISECONDS);
......
}
  • 6.当接收到新的投票信息时,节点会进行领导者PK,来判断谁更适合当领导者。如果投票信息中提议的节点比自己提议的节点更适合作为领导者,
    则该节点会更新投票信息,推荐投票信息中提议的节点作为领导者,并广播给所有节点,如代码所示
else if (totalOrderPredicate(n.leader, n.zxid,n.peerEpoch,proposedLeader, proposedZxid, proposedEpoch)) {
// 如果投票信息中提议的节点比自己提议的节点更适合作为领导者,则更新投票信息
// 并推荐投票信息中提议的节点
updateProposal(n.leader,n.zxid,n.peerEpoch);
// 将新的投票信息广播给所有节点
sendNotifications();
}
  • 7.如果自己提议的领导者赢得大多数选票,则执行步骤8,变更节点状态,退出选举,如果自己提议的领导者仍未赢得大多数选票,则执行步骤5,继续从接收队列中读取新的投票信息。
  • 8.最后,当节点提议的领导者赢得大多数选票时,则节点会根据投票结果,判断并变更节点状态(如变更为领导者或跟随者),然后退出选举,如代码所示
if (voteSet.hasAllQuorums()) {
......
// 根据投票结果,判断并设置节点状态
setPeerState(propsedLeader, voteSet);
// 退出领导者选举
Vote endVote = new Vote(proposedLeader, proposedZxid, logicalclock.get(), proposedEpoch);
leaveInstance(endVote);
return endVote;
......
}

注意

这里只是演示了一种选举情况,还有更多情况需要实践,比如接收到来自逻辑时钟的值比当前节点的值小的节点的投票哦信息,再比如接收到来自领导者的投票信息

如何从故障中恢复

在前面我们提到了ZAB协议的领导者选举,在我看来,它只是选举了一个适合当领导者的节点,然后把这个节点的状态设置成LEAEDING状态。此时,这个节点还不能作为主节点处理写请求,也不能使用领导职能(比如,它没办法阻止其他"领导者"广播提案)。也就是说,集群还没有从故障中恢复过来,而成员发现和数据同步会解决这个问题。
总的来说,成员发现和数据不同不仅让新领导者正式成为领导者,确立了它的领导关系,还解决了个副本数据冲突的问题,实现了数据副本的一致性,使集群能够正常处理写请求,这里需要注意的是:

  • 1.确立领导关系是指在成员发现(DISCOVERY)阶段,领导者和大多数跟随者建立连接,并再次确认各节点对自己当选领导者没有异议,从而确立自己的领导关系
  • 2.处理冲突数据是指在数据同步(SYNCHRONIZATION)阶段,领导者以自己的数据为准,解决各节点数据副本不一致的问题。
    理解这两点,有助于更好地理解ZooKeeper如何恢复故障,以及当主节点崩溃时,哪些数据会丢失、哪些数据不会丢失的原因等。换句话说,通过上述内容,我们能更好地理解ZooKeeper的节点故障容错能力

相关文章:

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

ZAB协议 ZooKeeper是如何选举领导者的。 首先我们来看看ZooKeeper是如何实现成员身份的? 在ZooKeeper中,成员状态是在QuorumPeer.java中实现的,为枚举型变量 public enum ServerState { LOOKING, FOLLOWING, LEADING, OBSERVING }其实&…...

在M1芯片安装鸿蒙闪退解决方法

在M1芯片安装鸿蒙闪退解决方法 前言下载鸿蒙系统安装完成后,在M1 Macos14上打开闪退解决办法接下来就是按照提示一步一步安装。 前言 重新安装macos系统后,再次下载鸿蒙开发软件,竟然发现打不开。 下载鸿蒙系统 下载地址:http…...

Linux基础-socket详解、TCP/UDP

文章目录 一、Socket 介绍二、Socket 通信模型三、Socket 常用函数1 创建套接字2 绑定套接字3、监听连接4、接受连接5、接收和发送数据接收数据发送数据 6、关闭套接字 四、Socket编程试验1、源码server.cclient.c 2、编译:3、执行结果 五、补充TCP和UDP协议的Socke…...

【菜单下拉效果】基于jquery实现二级菜单下拉效果(附完整源码下载)

Js菜单下拉特效目录 🍔涉及知识🥤写在前面实现效果🍧一、涉及知识🌳二、具体实现2.1 搭建一级菜单2.2 搭建二级菜单项2.3 引入js文件2.4 构建CSS文件 🐋三、源码获取🌅 作者寄语 🍔涉及知识 ht…...

如何使用resource-counter统计跨Amazon区域的不同类型资源数量

关于resource-counter resource-counter是一款功能强大的命令行工具,该工具基于纯Python 3开发,可以帮助广大研究人员跨Amazon区域统计不同类型资源的数量。 该工具在统计完不同区域的各类资源数量后,可以在命令行中输出并显示统计结果。res…...

nextTick的作用与原理

在 Vue 中,nextTick允许我们延迟执行一段代码,直到 Vue完成其当前的 DOM 更新周期。这使得我们可以在 DOM 更新后安全地访问和修改 DOM 元素。 一、Vue 的异步更新策略 Vue 采用了一种称为异步更新策略的机制。这意味着当数据发生变化时,Vue…...

mybatis工程需要的pom.xml,以及@Data 、@BeforeEach、@AfterEach 的使用,简化mybatis

对 “mybatis - XxxMapper.java接口中方法的参数 和 返回值类型&#xff0c;怎样在 XxxMapper.xml 中配置的问题” 这篇文章做一下优化 这个pom.xml文件&#xff0c;就是上面说的这篇文章的父工程的pom.xml&#xff0c;即&#xff1a;下面这个pom.xml 是可以拿来就用的 <?…...

微信小程序demo-----制作文章专栏

前言&#xff1a;不管我们要做什么种类的小程序都涉及到宣传或者扩展其他业务&#xff0c;我们就可以制作一个文章专栏的页面&#xff0c;实现点击一个专栏跳转到相应的页面&#xff0c;页面可以有科普类的知识或者其他&#xff0c;然后页面下方可以自由发挥&#xff0c;添加联…...

Linux migrate_type初步探索

1、基础知识 我们都知道Linux内存组织管理结构架构&#xff0c;顶层是struct pglist_data&#xff0c;然后再到struct zone&#xff0c;最后是struct page。大概的管理结构是这样的&#xff1a; 根据物理内存的地址范围可划分不同的zone&#xff0c;每个zone里的内存由buddy…...

i.MX 6ULL 裸机 IAR 环境安装

一. IAR 的安装请自行搜索 二. 使用最新版本的 IAR&#xff0c;需要修改 SDK 1. 在 SDK 的 core_ca7.h 加上 #include "intrinsics.h" /* IAR Intrinsics */ 2. debug 时需要修改每个工程下的 ddr_init.jlinkscript&#xff0c;参考链接 Solved: How to conn…...

cmake进阶:文件操作

一. 简介 前面几篇文章学习了 cmake的文件操作&#xff0c;写文件&#xff0c;读文件。文章如下&#xff1a; cmake进阶&#xff1a;文件操作之写文件-CSDN博客 cmake进阶&#xff1a;文件操作之读文件-CSDN博客 本文继续学习文件操作。主要学习 文件重命名&#xff0c;删…...

在UI界面中播放视频_unity基础开发教程

在UI界面中播放视频_unity基础开发教程 前言操作步骤结语 前言 之前我写过一篇在场景中播放视频的文章&#xff0c;但是在开发中有时候也会在UI的界面中播放视频&#xff0c;这期我们做一下在UI的界面中播放视频。 操作步骤 首先在场景中创建一个Raw Image&#xff0c;UI->…...

TypeScipt 联合类型 | 号的使用

联合类型有两种使用方法&#xff1a; 一种类型中多个可能的值。具有多种不同的类型中的一种。 一种类型中多个可能的值。 type isAye true | false;const aye:isAye true; const aye1:isAye false; const aye2:isAye 3; // Type number is not assignable to type isAye…...

MATLAB 变换

MATLAB 变换&#xff08;Transforms&#xff09; MATLAB提供了用于处理诸如Laplace和Fourier变换之类的变换的命令。转换在科学和工程中用作简化分析和从另一个角度查看数据的工具。 例如&#xff0c;傅立叶变换允许我们将表示为时间函数的信号转换为频率函数。拉普拉斯变换使…...

【005_音频开发_基础篇_ALSA_Codec_驱动-MA120x0P功放】

005_音频开发_基础篇_ALSA_Codec_驱动-MA120x0P功放 文章目录 005_音频开发_基础篇_ALSA_Codec_驱动-MA120x0P功放创作背景MA120X0P输出模式BTLSEPBTLSEBTL 硬件配置方式/硬件Limiter限幅器限幅器作用过程 主要寄存器操作指令 ma120x0p.cma120x0p.h 创作背景 学历代表过去、能…...

2、​​​​​​​FreeCAD模块与核心架构总结

FreeCAD作为一个开源的3D建模软件&#xff0c;其内部架构由多个模块组成&#xff0c;这些模块共同协作以支持软件的各种功能。本总结将基于提供的参考文档&#xff0c;对FreeCAD的核心模块、架构特性以及启动过程进行翻译和详细阐述。 核心模块概览 FreeCAD的核心模块主要包括…...

MySQL为什么默认引擎是InnoDB?

因为InnoDB特别强大,其支持很多东西 1.支持事务: 意味着对于一个复杂的SQL语句要么全部执行成功,要么全部失败,因为其底层是原子性的 2.支持并发(行级并发) 意味着面对高并发,多个用户可以同时访问一个表的不同行,不同行之间上锁,而不是给一个表上锁,这样就提高了高并发的性能和…...

K8s: Helm搭建mongodb集群(1)

mongodb 集群搭建 mongdb 部署前 需要创建 pvc, pv 和 sc&#xff0c;如果在云上会自动创建helm 应用中心: https://artifacthub.io 1 &#xff09;Helm 安装 mongodb A. 无本地存储配置&#xff0c;重启数据消失 在 https://artifacthub.io/packages/helm/bitnami/mongodb…...

应用分层和企业规范

目录 一、应用分层 1、介绍 &#xff08;1&#xff09;为什么需要应用分层&#xff1f; &#xff08;2&#xff09;如何分层&#xff1f;&#xff08;三层架构&#xff09; MVC 和 三层架构的区别和联系 高内聚&#xff1a; 低耦合&#xff1a; 2、代码重构 controlle…...

Flutter笔记:Widgets Easier组件库(1)使用各式边框

Flutter笔记 Widgets Easier组件库&#xff08;1&#xff09;&#xff1a;使用边框 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress o…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

go 里面的指针

指针 在 Go 中&#xff0c;指针&#xff08;pointer&#xff09;是一个变量的内存地址&#xff0c;就像 C 语言那样&#xff1a; a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10&#xff0c;通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

ArcGIS Pro+ArcGIS给你的地图加上北回归线!

今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等&#xff0c;设置经线、纬线都以10间隔显示。 2、需要插入背会归线&#xf…...