基于Raft算法的DLedger库分析

小夏 科技 更新 2024-01-29

在分布式系统应用中,高可用性和一致性经常面临问题,针对不同的应用场景,我们会选择不同的架构方式,比如 master-sl**e 和基于 ZooKeeper 的 master 选择。 随着时间的流逝,有一种方法可以基于筏算法自动选择主节点,它基于 paxos,并且做了一些简化和限制,例如增加了日志必须是连续的,并且只支持 leader、follower 和 candidate 三种状态,这使得算法相对容易理解和实现。

1)Dledger 是基于 OpenMessaging 发布的 Raft 实现的 J**A 类库,可以很容易地引用到系统中,满足其高可用、高可靠、强一致性的要求。

2)Raft将系统中的角色分为领导者、追随者和候选人

leader:接受客户端请求,定时发送心跳报文,将请求日志同步到跟随者,当日志同步到大多数节点时,告诉跟随者提交日志。 follower:接受并持久化 leader 同步的日志,待 leader 告知 leader 已准备好提交日志后再提交。 candidate:领导者选举过程中的临时角色,处于此状态的节点会发起投票并尝试选择自身作为主节点,选举成功后,处于此状态的节点将不存在

dledger 的实现大致可以分为两部分:

复制选举领导日志的整体架构,如下图所示

注:图为官网。

从上面的架构图中可以看出,有两个核心类:dledgerleaderelector 和 dledgerstore、election 和 file storage。 选择 leader 后,leader 接收到数据写入,并同步给其他 follower,这样就完成了整个 raft 写入过程。

从gitgub***idea引入后,我们发现整个**量很小,比较容易分析**。

选择 raft 的 master 的过程其实就是一个状态机的流程,当集群启动时每个节点的等待超时时间是随机的,当第一个节点的超时时间到达时,它会主动向其他节点发起投票,在收到超过一半的投票后, 会被提升为leader节点(投票过程是一个循环过程),同时发送心跳请求,其他候选节点在收到主节点的请求后,会自行变为follower节点。

term: term,每轮投票为一个 term,默认从 0 开始 仲裁机制:简单来说,就是不到一半,比如 3 个节点,2 个同意超时: 在选举时,每个节点的超时时间在一定范围内是随机的,可以保证整个状态机的驱动能够成功当选, 并且 DledgerLeaderElector 每 10 毫秒由线程重复执行一次maintainstate() 方法。 让我们关注他们状态的驱动因素:

转到核心方法 maintainascandidate()。

term : 投票轮次。 ledgerendtermleader:节点的当前投票轮次。 LedgerEndIndex:当前日志的最大序列,即下一个日志的开始 indexNextTimeToRequestVote:下一次投票的时间(随机) needincreasetermimmediately:是否立即投票,后面会解释 dledger 中每个节点的初始状态,所以第一轮刚刚初始化。 只有成员国nextterm()** 更改投票轮次。

进入核心方法handlevote(),主要用于根据自己的术语和请求者来判断是否为其他节点投票。

ledgerendindex因为在日志复制过程中每个节点的进度可能不同,所以在新一轮选举中,不能投票的被选举人的任期小于选举人的任期,被拒绝的候选人的任期大于选举人的任期,则选举人进行如下操作: 成为候选项(或保留候选项) 将 needincreaseimmediately 设置为 true。返回拒绝项未就绪,稍后会提到。 以下是附加说明:

选举者的下一个状态循环进入 maintainascandidate() 函数,然后由于 needincreaseimmediately 为 true,因此将更新项并重置计时器。 但是,投票不会立即发布(选举人的 currvotefor 仍然为空,因此可以对下一个投票的候选人投赞成票)。

在获得所有节点投票结果后,将对投票进行统计

在收到所有节点的票数后,进行仲裁,下图主要说明了这种情况。

acceptnum:agreesNotReadyTermnum:未准备好的金额(即结果是拒绝项未准备好) 没有时间重置 NextTimeToRequestVote,并立即发起另一次投票。 结合上述说明,这确保了被选中的人能够尽快获得这些未读节点的赞成票。

最后,经过多次投票后,当一个节点获得超过一半的票数时,它会更新其非 leader 角色并向其他节点发送心跳,其他节点在收到心跳信息后从候选者变为关注者。

dledger 作为 rocketmq ( version>=4.5.0)消息存储已经发布,基于dledger实现多节点缓存同步更新,基于日志复制副本容错处理,这里仅简单分析一下主要选择过程,在读取源码的过程中会涉及到很多j**a基础和netty的使用,比如aqs, completablefuture等,以帮助提高我们的编码能力。初始化时,dledger 将节点角色设置为候选者而不是追随者,这与原来的 raft 不同,节点角色转换过程也略有不同。 /wikihttps://www.usenix.org/system/files/conference/atc14/atc14-**ongaro.pdf

作者:京东物流郭青海.

*:京东云开发者社区自猿说技术**请注明**。

相似文章

    逆矩阵算法详解

    逆矩阵是指对于给定的方阵 即行数等于列数的矩阵 存在使得两者的乘积是统一矩阵 对角线上的元素为 ,其他元素为 如果矩阵存在逆矩阵,则逆矩阵通常用 a 表示。n n 矩阵 a 的逆矩阵 a 存在的条件是矩阵 a 是可逆的 也称为非奇异秩或全秩 即矩阵 a 的行列式 det a 不等于 。以下是计算逆矩...

    基于 Electron 和 Vue 打造集桌面管理、高效办公于一体的二屏系统

    一 项目简介 基于Electron和VUE,是集桌面管理和高效办公于一体的二级屏系统。二 功能的实现 自定义您的桌面 用户可以根据自己的喜好添加 小部件和便笺,以创建独特且个性化的桌面。这使用户可以轻松访问常用项目,同时将小部件和便笺添加到桌面以提醒或记录重要事项。多桌面支持 为了满足不同的使用场景...

    快速排序 高效的就地排序算法

    快速排序是一种常用的排序算法,它采用了分而治之的思想,与合并排序不同,快速排序是原位排序的,即不需要额外的空间来存储中间结果。在本文中,我们将了解快速排序的工作原理 工作原理以及它在对子数组进行排序时的作用。快速排序的算法步骤如下 哨兵分部 首先,我们需要选择一个基准编号作为哨兵。通常,我们选择数组...

    算法ICP备案的流程与周期

    在申请算法备案的过程中,了解流程和周期非常重要。一般情况下,申请算法ICP备案的流程包括以下步骤 第一步是提交申请。企业需要向相关部门提交算法备案申请,申请必须包括企业的基本信息 算法的相关信息 使用目的等。在提交申请之前,公司需要准备所有相关文件,并确保所提供的信息真实准确。第二步是审计。企业提交...

    递归算法的时间复杂度

    递归算法是一种在解决问题的过程中不断调用自身来完成任务的方法。它在编程中应用广泛,可以有效解决许多复杂的问题。然而,递归算法的时间复杂度通常难以确定,因为它涉及递归的深度和重复计算的情况。在本文中,我们将仔细研究递归算法的时间复杂度以及如何分析和优化它们。.递归算法概述。递归算法是一种通过不断调用自...