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/已写入日志的索引越多越好

状态维护

上图节点状态维护模型

ShutdownAbleThread 线程提供定时执行工作;等待执行两个特性

StateMaintainer 继承ShutdownAbleThread, 获得定时执行能力,定时执行维护状态的工作,维护工作分领导者,追随者,候选者

心跳

领导者通过状态维护线程定时发送心跳到其他节点(不发给自己),检测健康度。领导者收到心跳返回,统计,设置下一步动作准备。

心跳是选举的源头,跟随者记录心跳时间,跟随者状态维护线程检查收到心跳时间间隔,若超时转为候选者发起选举。

发送心跳

领导者定时发送心跳

1 准备和初始化统计量

2 发送心跳

2.1 跳过自身,心跳请求不发给自己

处理心跳

其他非leader节点接收心跳请求,处理

1  leader不在集群成员名单

dledger目前没有集群成员管理,实际不会出现

2  leader收到自己发来的心跳请求

这个在后面问题一章分析

-----------------------------------------分割线------------------------------------------

3  term检查

3.1 leader的term落后于本节点

3.2 term一致,leader是心跳发送者,正常

-----------------------------------------分割线------------------------------------------

4  同样是term检查,需要改变状态,加上线程锁

4.1 leader的term落后于本节点,返回告诉发起阶段,你term落后了

4.2 term一致

4.2.1  leader空

可能是term落后的节点,提升了term,又或是刚启动,设置leader,便可正常工作

4.2.2  leader是发起心跳节点,正常

4.2.3  leader不是发起节点,不一致

出现脑裂,然后网络正常,处理方法参看部署下一步行动

4.3  本节点term落后了

提升term,不需要发起投票

统计心跳返回结果

领导者心跳返回统计,为下一步行动准备

2.2 异步统计

2.2.1 节点存活记录,目前没有使用,应该是预留给集群成员管理

2.2.2 提前结束,2个条件

1)  正常返回数过半

对leader来说,最关心的是正常返回节点数量过半,这样就可以维持任期有效,因此,只要过半可以“下班”,多一个两个无关紧要

2)  正常返回数+term落后节点数过半

心跳最重要任务就是探测集群是否有效,同时,节点term落后,给予机会调整,这样保证集群的稳定性,不要急于发起选举,说到底,集群最重要的是正常工作,此时落后的节点正提升term,只要这些节点正常,正常节点就过半

2.2.3 总数累计

总数达到allNum.get() == memberState.peerSize(),所有心跳请求返回(包括连接不上),退出

* memberState.peerSize() 实为 memberState.peerSize()+1-1,peerSize从0开始,数量需+1,排除自己,数量-1

部署下一步心跳行动

领导者统计完成,依据统计结果部署下一步行动

3 等待

这里等待有两处,一个是latch,一个是线程sleep

我不确定,但我理解, latch可以提前退出,线程sleep时间固定,固定的这段时间是为了notReady退出条件的情况,那时notReady节点正提升term,故而留点时间,提升term完成,接收心跳检测,便可成为正常节点

4 统计完毕,部署下一步的行动

4.1 本节点term落后了,自身是leader,需立即重新选举

4.2 集群有效性

心跳最重要任务就是探测集群是否有效,同时,有些节点term落后,给予机会调整,保证集群的稳定性,不要急于发起选举

4.2.1  正常节点过半,心跳检测完成

4.2.2  有效节点过半

notReady节点此时提升term,立刻心跳,term赶上可正常工作,参看处理心跳4.2,上面3

4.2.3  leader不一致

单单是一个节点的leader不一致,不用立刻发起选举,但到这里,

memberState.isQuorum(succNum.get() + notReadyNum.get())=false,意味着过半的节点没通讯上,很可能是脑裂,而且自己处于小数一边,需立刻选举

4.2.4  到这里,过半节点没通讯上,心跳检测失败

跟随者(follower)

跟随者检测心跳接收时间间隔,若超过最大心跳接收时间间隔,转为候选者角色发起选举,这里有个小心思,体现细节,

问题

选举未分析出来的点

不是预期的leader

目前没有分析出怎么出现这种情况

系列文章

  • 架构,核心组件和rpc组件 完成
  • 心跳 完成
  • 选举 完成
  • 日志 完成
  • 存储和快照/状态机
  • 集成rocketmq rocketmq使用dledger实现消息存储复制;broker控制器 元数据复制
  • 集群成员变更  成员变更管理,节点的上线下线发现,dledger v0.4未实现,但计划中,未来版本实现
  • jraft  “double check”  多重分析,jraft比较忠实实现了raft算法,在dledger基础上,再研究jraft对raft更深入的认识
  • 27
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

中间件XL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值