Raft算法的Java实现

2023-11-16

自己这几天在看Redis的Sentinel高可用解决方案,Sentinel选主使用的是著名的Raft一致性算法,本文对Raft的选主作了介绍,具体的算法内容,请参考 Raft 论文

Raft的整体结构

Raft结构
Raft 通过选举一个高贵的领导人,然后给予他全部的管理复制日志的责任来实现一致性。

而每个 server 都可能会在 3 个身份之间切换:

  • 领导者
  • 候选者
  • 跟随者

而影响他们身份变化的则是 选举。
当所有服务器初始化的时候,都是 跟随者,这个时候需要一个 领导者,所有人都变成 候选者,直到有人成功当选 领导者。

角色轮换如下图:

而领导者也有宕机的时候,宕机后引发新的 选举,所以,整个集群在选举和正常运行之间切换,具体如下图:

从上图可以看出,选举和正常运行之间切换,但请注意, 上图中的 term 3 有一个地方,后面没有跟着 正常运行 阶段,为什么呢?

答:当一次选举失败(比如正巧每个人都投了自己),就执行一次 加时赛,每个 Server 会在一个随机的时间里重新投票,这样就能保证不冲突了。所以,当 term 3 选举失败,等了几十毫秒,执行 term 4 选举,并成功选举出领导人。

接着,领导者周期性的向所有跟随者发送心跳包来维持自己的权威。如果一个跟随者在一段时间里没有接收到任何消息,也就是选举超时,那么他就会认为系统中没有可用的领导者,并且发起选举以选出新的领导者。

要开始一次选举过程,跟随者先要增加自己的当前任期号并且转换到候选人状态。然后请求其他服务器为自己投票。那么会产生 3 种结果:

a. 自己成功当选
b. 其他的服务器成为领导者
c. 僵住,没有任何一个人成为领导者

注意:

  1. 每一个 server 最多在一个任期内投出一张选票(有任期号约束),先到先得。
  2. 要求最多只能有一个人赢得选票。
  3. 一旦成功,立即成为领导人,然后广播所有服务器停止投票阻止新得领导产生。

僵住怎么办? Raft 通过使用随机选举超时时间(例如 150 - 300 毫秒)的方法将服务器打散投票。每个候选人在僵住的时候会随机从一个时间开始重新选举。

以上,就是 Raft 算法对选主的介绍,非常简短,具体的还是要看一边论文才能搞清楚,直接看代码基本看不懂。

实现代码

我在网上看到的都是golang语言的实现,作为一个Java程序员想找到一份Java的实现真难啊,蚂蚁金服开源了他们的JRaft实现,可是毕竟实现的非常完美,代码就有点难看懂了。

启动类就是做一下对自身节点的ip port的包装,

public class RaftNodeBootStrap {
   

    public static void main(String[] args) throws Throwable {
   
        main0();
    }

    public static void main0() throws Throwable {
   
        String[] peerAddr = {
   "localhost:8775","localhost:8776","localhost:8777", "localhost:8778", "localhost:8779"};

        NodeConfig config = new NodeConfig();

        // 自身节点
        config.setSelfPort(Integer.valueOf(System.getProperty("serverPort")));

        // 其他节点地址
        config.setPeerAddrs(Arrays.asList(peerAddr));

        Node node = DefaultNode.getInstance();
        node.setConfig(config);

        node.init();

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
   
            try {
   
                node.destroy();
            } catch (Throwable throwable) {
   
                throwable.printStackTrace();
            }
        }));
    }    

重点在node.setConfig()init()两个方法

 @Override
    public void setConfig(NodeConfig config) {
   
        this.config = config;
        stateMachine = DefaultStateMachine.getInstance();
        logModule = DefaultLogModule.getInstance();

        peerSet = PeerSet.getInstance();
        for (String s : config.getPeerAddrs()) {
   
            Peer peer = new Peer(s);
            peerSet.addPeer(peer);
            if (s.equals("localhost:" + config.getSelfPort())) {
   
                peerSet.setSelf(peer);
            }
        }

        RPC_SERVER = new DefaultRpcServer(config.selfPort, this);
    }

init对自己的同伴节点做初始化,最后一行,开启了一个RPCServer,RPCServer的功能看过Raft论文的应该都清楚,接收投票RPCVoteRequest, 和附加日志 RPCLogAppendRequest (心跳也是日志附加Request,只是日志内容为null)

public void init() throws Throwable {
   
        if (started) {
   
            return;
        }
        synchronized (this) {
   
            if (started) {
   
                return;
            }
            RPC_SERVER.start();

            consensus = new DefaultConsensus(this);
            delegate = new ClusterMembershipChangesImpl(this);

            RaftThreadPool.scheduleWithFixedDelay(heartBeatTask, 500);
            RaftThreadPool.scheduleAtFixedRate(electionTask, 6000, 500);
            RaftThreadPool.execute(replicationFailQueueConsumer);

            LogEntry logEntry = logModule.getLast();
            if (logEntry != n
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Raft算法的Java实现 的相关文章

  • 获取无平方数的列表

    获得该值的一种方法是自然数 1 n 我们对每个因子进行因式分解 看看它们是否有重复的质因数 但这对于大的情况来说会花费很多时间n 那么有没有更好的方法从 1 中获取无平方数n 您可以使用埃拉托斯特尼筛法的修改版本 取一个布尔数组 1 n 预
  • 如何找到最长的回文子序列(不是它的长度)

    我想找出字符串中最长的回文子序列 我到处都找到了找出子序列长度的算法 并声明该算法也可以扩展以返回子序列 但我没有找到如何实现的 有人能解释一下我怎样才能得到序列吗 既然你提到了链接最长回文子序列 http www geeksforgeek
  • 给定两个(大)点集,我如何有效地找到彼此最接近的点对?

    我需要解决一个计算问题 该问题归结为搜索两个集合之间最接近的点对 问题是这样的 给定欧几里德空间中的一组点 A 和一组点 B 找到所有对 a b 使得 b 是 B 中与 a 最近的点 a 是 A 中与 b 最近的点 集合 A 和 B 的大小
  • 如何使用KDTrees实现最近邻搜索?

    所以 我正在实施一个KD Tree http en wikipedia org wiki Kd tree进行最近邻搜索 我已经构建了树部分 但我认为我没有完全理解搜索部分 关于遍历树来搜索邻居 维基百科文章如下 Starting with
  • 如何设置K-means openCV c++的初始中心

    我正在尝试使用 OpenCv 和 Kmeans 对图像进行分割 我刚刚实现的代码如下 include opencv2 objdetect objdetect hpp include opencv2 highgui highgui hpp i
  • 交换两个向量之间的值,使两个向量的 max_element 之和最小

    这是 Codechef 的问题 但请耐心等待 https www codechef com ZCOPRAC problems ZCO16001 https www codechef com ZCOPRAC problems ZCO16001
  • 在无向图中查找强连通分量

    我想在无向图中找到强连接的组件 即如果我从节点开始A然后我会回到节点A并且每条边都被恰好访问一次 对于有向图可以使用Tarjan算法来寻找强连通分量 但是对于无向图怎么办 我认为您错过了强连通分量的含义 强连接组件 如果所有顶点对之间都存在
  • 加密成本高,解密成本低

    我希望该用户 攻击者加密数据并发送给服务器 现在我想要一种与标准算法完全相反的算法 使用快 难以解密 即很难使用服务器发送的密钥来加密密码等数据 以防止随机攻击 但很容易解密这样服务器在验证用户时消耗的时间非常少 但是对于攻击者来说 每次使
  • C 中的菱形数组排序

    我有以下 C 语言作业 我基本上需要一种方法而不是解决方案 我们有一个 13 x 13 的数组 在数组中 我们有一个需要考虑的菱形形状 该菱形之外的所有内容都初始化为 1 不重要 下面的 5 x 5 数组示例 x x 1 x x x 2 2
  • 缩短文本并仅保留重要句子

    德国网站 nandoo net 提供了缩短新闻文章的可能性 如果使用滑块更改百分比值 文本会发生变化并且某些句子会被遗漏 您可以在这里看到它的实际效果 http www nandoo net read article 299925 http
  • 如何查找给定字符串中仅出现一次的第一个字符[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 线性代数如何在算法中使用?

    我的几个同行都提到 学习算法时 线性代数 非常重要 我研究了各种算法并学习了一些线性代数课程 但我没有看到其中的联系 那么线性代数如何应用在算法中呢 例如 图的连接矩阵可以带来哪些有趣的事情 三个具体例子 线性代数是现代 3D 图形的基础
  • 如何高效地在屏幕上精确绘制N个点?

    这听起来是一个简单的问题 但我发现要获得良好的性能是非常棘手的 我提出的第一个算法是随机绘制点 从一组中检查是否已绘制 否则绘制 如果我们只绘制几个点 那么这种方法效果很好 但当我们接近填满屏幕时 速度会灾难性地减慢 我想出的最好的方法是构
  • 使用主方法求解 T(n) = 2T(n/2) + n/log n 和 T(n) = 4T(n/2) + n/log n 之间的差异

    我最近偶然发现了一个资源 其中 2T n 2 n log ntypeMM 宣布复发无法解决 我接受它作为一个引理 直到今天 另一种资源被证明是矛盾的 在某种意义上 根据资源 下面的链接 其中的 Q7 和 Q18 是建议 分别在问题中的1和2
  • 高维最近邻搜索的最佳数据结构

    我实际上正在处理高维数据 50 000 100 000 个特征 并且必须对其执行最近邻搜索 我知道随着维度的增长 KD 树的性能很差 而且我还了解到 一般来说 所有空间分区数据结构都倾向于对高维数据执行详尽的搜索 此外 还有两个重要事实需要
  • 固定大小集以包含给定集的最大数量

    我有大约 1000 组尺寸 1 4 1 3 3 5 6 4 5 6 7 5 25 42 67 100 是否有可能找到包含最大数量的给定集合的大小为 20 的集合 检查每一个100 80 20 集 效率低下 我不太确定这是 NP 完全的 考虑
  • 如何将一组重叠范围划分为不重叠范围?

    假设您有一组范围 0 100 一 0 75 b 95 150 c 120 130 d 显然 这些范围在某些点上重叠 您将如何剖析这些范围以生成不重叠范围的列表 同时保留与其原始范围相关的信息 在本例中为范围后面的字母 例如 运行算法后的上述
  • 最慢的计算复杂度(Big-O)

    在这些算法中 我知道 Alg1 是最快的 因为它是 n 平方的 接下来是 Alg4 因为它是 n 的立方 然后 Alg2 可能是最慢的 因为它是 2 n 这应该具有非常差的性能 然而Alg3和Alg5在我的阅读速度方面还没有遇到过 这两种算
  • 点集子集的最小周长凸包

    给定平面上的 n 个点 没有 3 个共线 给定数字 k 找到 k 个点的子集 使得 k 个点的凸包在 k 个点的子集的任何凸包中具有最小周长 我可以想到一个简单的方法 运行时间为 O n k k log k 找到大小为 k 的每个子集的凸包
  • 无需构建树即可预测霍夫曼压缩比

    我有一个二进制文件 我知道其中每个符号出现的次数 如果我要使用霍夫曼算法压缩它 我需要预测压缩文件的长度 我只对假设的输出长度感兴趣 而不对单个符号的代码感兴趣 因此构建霍夫曼树似乎是多余的 作为一个例子 我需要得到类似的东西 包含 4 个

随机推荐

  • [转] 英文写作中分号和冒号的使用

    我们先来了解下分号和冒号的作用 分号的主要作用是来连接两个在语法上平等的成分 冒号的主要作用是引起读者对冒号后面内容的注意力 下面总结下规则 用分号的情况 1 用分号连接两个独立的句子 两个独立的句子不能够用逗号隔开 如果用逗号 必须逗号后
  • idea忽略.iml文件

    1 点击file文件下的设置中 2 点下file types 文件类型 进入到file types窗口 如图 然后点击忽略文件那添加需要忽略的类型
  • 自用HTML+CSS学习笔记

    HTML CSS学习笔记 1 Web标准 Web标准也称为网页标准 由一系列的标准组成 大部分由W3C World Wide Web Consortium 万维网联盟 负责制定 由三个组成部分 HTML 负责网页的结构 页面元素和内容 CS
  • IT的教育

    IT的教育 李颜芯 CSDN的网友大家好 欢迎大家收看这一起的CSDN视频访谈节目 今天我们请到了两位嘉宾 一位是 金旭亮 老师 一位是 金戈 老师 两位老师作一下自我介绍怎么样 金旭亮 我先介绍一下吧 我叫金旭亮是北京理工大学的讲师 我在
  • 怎样把pdf转换成word-多语言ocr支持

    http jingyan baidu com article 86fae34699bb4e3c49121a23 html PDF格式良好的视觉阅读性和通用性使得PDF文件的使用越来越广泛了 网络上的PDF资料也越来越多 但是我们往往想要提出
  • 【大屏】 amap + echarts 踩坑以及避免办法

    amap echarts 踩坑以及避免办法 大屏 踩坑 代码 大屏 html body container margin 0 padding 0 width 5376px height 1944px background color 000
  • softmax用于分类问题/逻辑回归

    参考 d2l 线性回归问题最后输出一个参数用于预测 多分类问题最后输出多个维度的数据 多少个output channels就有多少个类别 softmax是一种激活函数 它常见于分类问题的最后一层激活函数 目的是让输出属于一个概率密度函数 我
  • AI「领悟」有理论解释了!谷歌:两种脑回路内部竞争,训练久了突然不再死记硬背...

    梦晨 发自 凹非寺量子位 公众号 QbitAI 谷歌PAIR团队不久前撰文介绍了AI的 领悟 Grokking 现象 训练久了突然不再死记硬背 而是学会举一反三 有了泛化能力 不出一个月 另一只团队 主要成员来自DeepMind 表示 已经
  • 说实话,其实Spring Security并没有看起来那么复杂(附源码)

    权限管理是每个项目必备的功能 只是各自要求的复杂程度不同 简单的项目可能一个 Filter 或 Interceptor 就解决了 复杂一点的就可能会引入安全框架 如 Shiro Spring Security 等 其中 Spring Sec
  • Android Studio使用技巧:添加Module依赖

    今天在学习使用Volley的时候 下载好了Volley的Module文件 成功import到了Android Studio 但是却不知道怎么在自己的项目 Module 里使用 经朋友指点才知道原来还有给自己的项目添加Module Depen
  • JVM反射的实现

    实现方式 有两种不同的实现方式 一种是本地实现 一种是动态实现 JVM开始运行之后 方法的代码和入口地址都能获取到 想要通过反射调用方法 无非就是找到方法地址 然后将参数传递进去执行 本地实现就是使用native方法直接调用方法 但是这种方
  • PS调节图片:拉伸、变形

    一 对图片进行变形处理 打开PS软件 选中需要处理的图片 ctrl J复制一层图层 点击编辑选项 在下拉菜单里找到变换 变形选项 即可对图片进行变形操作 注意变形的图片下边还有一层图形 那即是我们复制图层的效果 复制图层相当于在图片上面加了
  • 计算机网络基础知识总结及思维导图(六)应用层

    文章目录 六 应用层 6 1 域名系统DNS 6 1 1 基础概念 6 1 2 域名服务器 6 2 文件传送协议 6 2 1 介绍 6 2 2 FTP协议 6 2 3 简单文件传送协议TFTP 6 3 远程终端协议TELNET 6 4 万维
  • 哪个网站云服务器最便宜,哪家云服务器比较便宜

    哪家 云服务器 是一种简单高效 安全可靠 处理能力可弹性伸缩的计算服务 其管理方式比物理服务器更简单高效 用户无需提前购买硬件 即可迅速创建或释放任意多台云服务器 我们在选择云服务器时 多从CPU 内存和磁盘特性等方面来对比 在这些因素相差
  • webdriver在浏览器中显示版本不对的解决方法

    相信看到这的小伙伴已经安装好了selenium包了 pip3 install selenium 可能是运行的时候出现这样的错误 SessionNotCreatedException Message session not created T
  • k8s系列——部署k8s集群

    1 环境准备 1 1 安装操作系统 此处选用centos 7 操作系统进行安装操作 1 2 关闭防火墙 systemctl stop firewalld systemctl disable firewalld 1 3 关闭selinux s
  • java使用okhttp3实现gofastdfs上传

    1 maven
  • [数值计算-7]:一元n次非线性方程求解-单点盲探-牛顿迭代法&Python法代码示例

    作者主页 文火冰糖的硅基工坊 https blog csdn net HiWangWenBing 本文网址 https blog csdn net HiWangWenBing article details 119813740 目录 1 一
  • 【OPENCV_系列电子PDF图书连载】计算机视觉从入门到精通完整学习路线专栏

    OPENCV PDF图书连载之 图像的几何变换 一 图像几何变换 1 3 a 图像坐标仿射 仿射自定义代码展示 warpAffine pointsAffine 自定义包 from img pakage ocv import warpAffi
  • Raft算法的Java实现

    自己这几天在看Redis的Sentinel高可用解决方案 Sentinel选主使用的是著名的Raft一致性算法 本文对Raft的选主作了介绍 具体的算法内容 请参考 Raft 论文 Raft的整体结构 Raft 通过选举一个高贵的领导人 然