dledger原理源码分析系列(三)-选主
简介
dledger是openmessaging的一个组件, raft算法实现,用于分布式日志,本系列分析dledger如何实现raft概念,以及dledger在rocketmq的应用
本系列使用dledger v0.40
本文分析dledger的选主
关键词
Raft
Openmessaging
心跳/选主
参考资料
In Search of an Understandable Consensus Algorithm raft论文简版
选主
选主是dledger的关键特性,主节点承担处理Client请求,复制日志到跟随者节点,dledger通过心跳发起选举。
关键属性
本节介绍关键属性,为下面分析准备
- term 任期/轮次
任期: 新的选举开始到下一个选举开始,左闭右开的时间区间,包括选举期和工作期两部分
轮次:任期内选举的轮次,任期内可多轮不提升term选举
- needIncreaseTermImmediately
需要立即增加term的设置,只提升任期,但不对其他节点发起投票请求,用于term落后的节点
- nextTimeToRequestVote
下次请求投票时间
System.currentTimeMillis() + minVoteIntervalMs + random.nextInt(maxVoteIntervalMs - minVoteIntervalMs)
dledger根据情况有不同的设定,下次发起选举时间的差异正是选举的关键
- currVotedFor
本节点投票给谁了,该值提升term时设置为null;该值设置地方只有一处,处理投票handlerVote,即,不提升term节点,投票给谁不会改变
- currTerm
节点当前所处任期
- ledgerEndTerm/ledgerEndIndex
已写入日志的term;已写入日志的索引
两个数据是节点成为leader的关键数据,作为leader已写入日志的term/已写入日志的索引越多越好
分析
选举分3块,第一投票邀请;第二投票;第三投票统计,部署下一步操作,其中
投票邀请
候选者定时维护状态,maintainAsCandidate方法发起投票邀请,邀请其他节点(包括自己)为自己投票

1 检查是否符合投票条件,投票时间到 或者 设置了需要立即提升term
2 double check 节点处于候选者角色
3 是否提升term
lastParseResult是上一轮发起投票分析结果,参考后面投票统计
只需提升term,追赶上该轮投票的term,不发起投票邀请
4 获取节点的已写入的term/index
5 重置needIncreaseTermImmediately
term落后,设置该标记为true,提升term后,恢复默认
6 邀请节点投自己一票,邀请也发给自己
投票
节点,包括发起投票的领导者,处理投票请求

1 投票发起者的合法性检查
投票请求的leader是发起者,投票实际是拉票,邀请其他节点投自己一票
1.1 leader是否组内的节点
目前版本不知道集群变更,实际不会出现
1.2 不应该出现的leader
参看问题分析
-----------------------------------------分割线------------------------------------------

2 检查已写入日志term和index
这个好理解,想做leader,写入的日志应该比我多;比我少的,没资格让我投你票
-----------------------------------------分割线------------------------------------------
term相关检测

3 请求节点的term < 本节点term,拒绝投票,请求节点的term落后了
4 term一致
4.1 currVoteFor为空,还没投票
后面的检测没问题的话,本节点投票给发起节点
4.2 currVoteFor不为空,已投票,而且投的是发起节点
4.3 currVoteFor不为空,投票给其他节点了
下面继续细分,本节点是否已有leader,这里考虑一个问题,有无可能currVoteFor为空,并且有leader?
不可能,分两种情况,
- 本节点是跟随者,本节点未进入本term选举,本节点term小于发起者term
- 本节点是候选者,提升term置空currVoteFor,成为候选者要置空leader
4.4 本节点term落后了
设置needIncreaseTermImmediately,提升term,但不发起投票请求
5 发起节点term与本节点已写入日志term比较
与2相同,发起节点资格不够,不能投你
-----------------------------------------分割线------------------------------------------

6 本节点用户设置优先当领导,而且条件符合,不投票给发起节点,自己优先
7 最后,投票给请求节点
投票统计

7 首先准备好统计量
-----------------------------------------分割线------------------------------------------

统计不详细分析,看注释便清楚
-----------------------------------------分割线------------------------------------------

7.3 提早通过latch等待,3个条件
1. 已有选出leader
2. 票数已过半,自己将成为leader
3. 本节点未够票,剩下的票不过半,即,也没有其他人选上
7.4 统计所有节点数
总数达到allNum.get() == memberState.peerSize(),所有心跳请求返回(包括连接不上),退出
* memberState.peerSize() 实为 memberState.peerSize()+1-1,peerSize从0开始,数量需+1,排除自己,数量-1
部署下一论投票行动

8 投票统计结果决定下一步投票行动
8.1 本节点term落后了
提升任期,再发起投票请求,这点跟投票者不一样,投票者term落后设置needIncreaseTermImmediately=true,即只提升,不发起投票请求,这样做容易理解,选出主节点,需要争票的少,投票的多,投票发起节点只有一个,投票的节点多个
8.2 集群已有leader,无需再发起投票,但不立即转为follower,延长下次投票,等待下一个leader的心跳,调整为正确的leader,便进入正常工作
8.3 有效返回节点数过少,通常是网络原因,只有等
8.4 除去日志比自身完整的节点,还不够票数当选,让贤,延迟下次投票邀请的时间,让其他节点发起投票
8.5 当选leader
8.6 加上term落后的节点够票数让本节点当选
此时,term落后的节点提升term,立即选举增加本节点当选的几率,但REVOTE_IMMEDIATELY实际没使用
8.7 选票分散,提升任期,投票
9 选上了,赶快坐上宝座当领导
总结:行动的目标是尽快选到领导者,策略上尽量逼近目标无疑是正确的。
有效性
本节去掉异常情况,只看选举的主体流程,分析一下选主的有效性,dledger的规则/逻辑怎样让分布节点获得过半票数

去掉的异常情况
1 本节点term落后
2 有效返回过少
3 写入日志term/index比投票节点小
4 投票节点term小于本节点
选举主体:
1 已经选出领导者
2 获得投票过半
3 投票分散,未能选为领导者
1/2 两种情况选举完成
3,提升term;设置下次投票时间,投票时间有范围的随机值,只要有不多于2个节点率先发起投票,其他节点投票,这就可以选出主节点
问题
选举未分析出来的点
不是预期的leader
系列文章
相关文章:
dledger原理源码分析系列(三)-选主
简介 dledger是openmessaging的一个组件, raft算法实现,用于分布式日志,本系列分析dledger如何实现raft概念,以及dledger在rocketmq的应用 本系列使用dledger v0.40 本文分析dledger的选主 关键词 Raft Openmessaging 心跳/选…...
如何修改PDF文档的作者名称?
要修改一个 PDF 文档的作者名称,你可以按照以下步骤进行操作: 1. **使用 Adobe Acrobat**(如果有): - Adobe Acrobat 是一个功能强大的 PDF 编辑工具,支持修改文档属性信息,包括作者名称。打开…...
从笔灵到AI去痕:全方位提升内容创作与学术诚信
内容为王,在内容创作的世界中尤为重要。然而,面对写作时常常感到无从下手:有时缺乏灵感,有时难以表达清楚自己的想法。AI写作助手的出现,为这些问题提供了创新的解决方案,极大地改变了内容创作的过程。 今…...
考试如果出现汉诺塔问题怎么办?
对于这道题来说 就按照测试案例里的数字进行输入 测试案例用100 那这三只鸡的具体最多能有多少只鸡呢? 用总数除以这只鸡的单价>>>>>>>即为这只鸡最多有 >>>>>>>> n / 单价 修改后 >>>>> 不只适…...
导出word模板开发记录
exportWordDocx.js import JSZipUtils from “jszip-utils” import Docxtemplater from “docxtemplater” import {saveAs} from “file-saver” import PizZip from “pizzip” const exportWordDocx (demoUrl, docxData, fileName) > {// 读取并获得模板文件的二进制…...
PHP爬虫类的并发与多线程处理技巧
PHP爬虫类的并发与多线程处理技巧 引言: 随着互联网的快速发展,大量的数据信息存储在各种网站上,获取这些数据已经成为很多业务场景下的需求。而爬虫作为一种自动化获取网络信息的工具,被广泛应用于数据采集、搜索引擎、舆情分析…...
用Python将PowerPoint演示文稿转换到图片和SVG
PowerPoint演示文稿作为展示创意、分享知识和表达观点的重要工具,被广泛应用于教育、商务汇报及个人项目展示等领域。然而,面对不同的分享场景与接收者需求,有时需要我们将PPT内容以图片形式保存与传播。这样能够避免软件兼容性的限制&#x…...
机电公司管理小程序的设计
管理员账户功能包括:系统首页,个人中心,用户管理,管理员管理,客户管理,公告管理,考勤管理,请假管理 微信端账号功能包括:系统首页,公告,机电零件&…...
SQL中的子查询和CTE(with ....as..)
第一次看到with as 这种类似于python中读文件的写法还是挺疑惑的,其实它是CTE,功能和子查询很类似但又有不同点,在实际应用场景中具有着独特作用。 子查询 子查询是在主查询中的嵌套查询,可以出现在SELECT、FROM、WHERE等子句中…...
Cesium 基本概念:创建实体和相机控制
基本概念 Entity // 创建一个实体 const entity_1 viewer.entities.add({position: new Cesium.Cartesian3(0, 0, 10000000),point: {pixelSize: 10,color: Cesium.Color.BLUE} });// 通过经纬度创建实体 const position Cesium.Cartesian3.fromDegrees(180.0, 0.0); // 创…...
vue使用scrollreveal和animejs实现页面滑动到指定位置后再开始执行动画效果
效果图 效果链接:http://website.livequeen.top 介绍 一、Scrollreveal ScrollReveal 是一个 JavaScript 库,用于在元素进入/离开视口时轻松实现动画效果。 ScrollReveal 官网链接:ScrollReveal 二、animejs animejs是一个好用的动画库…...
在Ubuntu 16.04上安装和配置GitLab的方法
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 GitLab CE(Community Edition)是一个开源应用程序,主要用于托管 Git 仓库,并提供额…...
STM32的SPI通信
1 SPI协议简介 SPI(Serial Peripheral Interface)协议是由摩托罗拉公司提出的通信协议,即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在ADC、LCD等设备与MCU间,使用于对通信速率要求较高的场合。 …...
机器学习引领教育革命:智能教育的新时代
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀目录 📒1. 引言📙2. 机器学习在教育中的应用🌞个性化学习🌙评估与反馈的智能化⭐教学资源的优…...
6月29日,每日信息差
第一、位于四川省绵阳市的中广核质子治疗装备制造基地正式通过竣工验收,为全球装机数量和治疗患者数量最多的国际领先质子治疗系统全面国产化奠定了坚实基础。质子治疗作为目前全球最尖端的肿瘤放射治疗技术之一,与传统放疗技术相比,质子治疗…...
SpringCloud中复制模块然后粘贴,文件图标缺少蓝色方块
再maven中点击+号,把当前pom文件交给maven管理即可...
JS乌龟吃鸡游戏
代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>乌龟游戏</title><script type"text/javascript">function move(obj){//乌龟图片高度var wuGui_height 67;…...
第十节:学习ConfigurationProperties类来配置pojo实体类参数(自学Spring boot 3.x的第二天)
大家好,我是网创有方 。这节记录下如何使用ConfigurationProperties来实现自动注入配置值。。实现将配置文件里的application.properties的参数赋值给实体类并且打印出来。 第一步:新建一个实体类WechatConfig package cn.wcyf.wcai.config;import org…...
如何学习Node.js
Node.js是一个开源、跨平台的JavaScript运行环境,它允许你在服务器端使用JavaScript。以下是一些步骤和资源,可以帮助你开始学习Node.js: ### 1. 基础知识 首先,确保你熟悉JavaScript语言的基础。Node.js是基于JavaScript的&…...
云计算基础知识
前言: 随着ICT技术的高速发展,企业架构对计算、存储、网络资源的需求更高,急需一种新的架构来承载业务,以获得持续,高速,高效的发展,云计算应运而生。 云计算背景 信息大爆炸时代:…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
