ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Raft算法_SOFAJRaft源码学习_(一、背景及选主演示)

2021-12-23 11:31:48  阅读:162  来源: 互联网

标签:选主 127.0 CounterServer1 SOFAJRaft CounterServer3 0.1 源码 集群 leader


背景

raft算法原理,建议参考raft官网:https://raft.github.io/

强烈推荐观看raft的流程动画,方便直观理解算法过程

动画地址:http://thesecretlivesofdata.com/raft/

本系列通过阅读SofaJRaft源码,并在本地运行SofaJRaft自带的Counter演示程序,学习了解raft算法在工程中的具体实现。

SofaJRaft源码地址:https://github.com/sofastack/sofa-jraft

对应的文档地址:https://www.sofastack.tech/projects/sofa-jraft/jraft-user-guide/

本项目阅读和演示的代码版本:

<dependencies>

        <!-- jraft -->
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>jraft-core</artifactId>
            <version>1.3.9</version>
        </dependency>
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>jraft-rheakv-core</artifactId>
            <version>1.3.9</version>
        </dependency>
        <!-- jsr305 -->
        <dependency>
            <groupId>com.google.code.findbugs</groupId>
            <artifactId>jsr305</artifactId>
            <version>3.0.2</version>
        </dependency>
        <!-- bolt -->
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>bolt</artifactId>
            <version>1.6.4</version>
        </dependency>
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>hessian</artifactId>
            <version>3.3.6</version>
        </dependency>
        <!-- log -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.21</version>
        </dependency>
        <!-- disruptor -->
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.3.7</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <!-- protobuf -->
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!-- protostuff -->
        <dependency>
            <groupId>io.protostuff</groupId>
            <artifactId>protostuff-core</artifactId>
            <version>1.6.0</version>
        </dependency>
        <dependency>
            <groupId>io.protostuff</groupId>
            <artifactId>protostuff-runtime</artifactId>
            <version>1.6.0</version>
        </dependency>
        <!-- rocksdb -->
        <dependency>
            <groupId>org.rocksdb</groupId>
            <artifactId>rocksdbjni</artifactId>
            <version>6.22.1.1</version>
        </dependency>
        <!-- java thread affinity -->
        <dependency>
            <groupId>net.openhft</groupId>
            <artifactId>affinity</artifactId>
            <version>3.1.7</version>
        </dependency>
        <!-- metrics -->
        <dependency>
            <groupId>io.dropwizard.metrics</groupId>
            <artifactId>metrics-core</artifactId>
            <version>4.0.2</version>
        </dependency>
</dependencies>

选主

通过raft算法的原理可以知道,raft集群是一主(learder)多从(follower)的结构,leader负责接收客户端(client)的请求,处理并记录日志,然后leader将日志复制到所有的follower,达到数据冗余备份的目的。

当集群中有follower宕机,在不超过半数的情况下,集群仍然可以正常提供服务,follower恢复后,可以从leader复制快照(snapshot),以及快照点之后的所有日志记录,用于恢复内存中的数据,以追赶上集群状态。

当集群中的leader宕机后,所有的follower将选举出一名新的leader替代原有的leader,此过程即“选主”。

Counter演示程序

在源码分析之前,先演示一遍raft集群的启动及选主程序,直观的感受一下流程。

该程序来源于SofaJRaft源码,业务功能很简单,就是一个计数器,从零开始,每次客户端调用,都可以自增服务端内存中的整数值。

服务器启动

服务器执行入口是源码中的CounterServer的main方法 

我这里会在idea中启动3个本地服务host,模拟一主两从的集群结构。

CounterServer1、 CounterServer2、CounterServer3 是3个服务器,执行入口都是上面说的同一个main方法,但是启动参数有细微差别:

CounterServer1的启动参数:

/tmp/server1 counter 127.0.0.1:8181 127.0.0.1:8181,127.0.0.1:8182,127.0.0.1:8183

CounterServer2的启动参数:

/tmp/server2 counter 127.0.0.1:8182 127.0.0.1:8181,127.0.0.1:8182,127.0.0.1:8183

CounterServer3的启动参数:

/tmp/server3 counter 127.0.0.1:8183 127.0.0.1:8181,127.0.0.1:8182,127.0.0.1:8183

逗号分隔的4个参数,第一个是服务目录,第二个是group名称,第三个是服务ip,第四个是group配置。

其中,group名称需要一样,作为3个服务器加入的同一个集群的标志;因为是本机演示,所以服务ip都是一样的,靠端口区分;最后,group配置,其实就是一串服务ip列表,保存该集群的所有ip地址。

接下来,我们依次启动CounterServer1(端口8181)、 CounterServer2(端口8182)、CounterServer3(端口8183)

可以看到“Start the RaftGroupService successfully.”,表示服务器启动完成。

随后,CounterServer1开始发起选举,投自己一票,并向CounterServer2和CounterServer3要选票。 从上图可以看到,CounterServer3返回了granted=true,表示CounterServer3同意了CounterServer1的自荐请求。加上CounterServer1自己投自己的一票,2票同意超过了集群3台服务器的半数,所以最后CounterServer1成功成为了集群的leader:“become leader of group”。

我们再看看CounterServer3的日志情况:

可以看到,CounterServer3收到了来自CounterServer1的preVote和Vote请求,并没有表示异议。最后开始成为集群的follower,认可CounterServer1为leader。

 再看看CounterServer2的日志:

也有类似的收到 CounterServer1的preVote和Vote请求,以及认可CounterServer1为leader。

服务器重新选主

这个时候,我们的3台服务器的小集群已经到达了可对外服务的稳定状态,CounterServer1作为leader,CounterServer2和CounterServer3作为follower。

我们接下来模拟一下leader挂掉的场景,把CounterServer1的进程终止掉

 然后发现CounterServer3开始选举自己为leader,并发送选举请求给 CounterServer2,且收到了认可回复:

 最后,CounterServer3成为了集群的新领导者,然后不断尝试重新连接已经挂掉的CounterServer1:

 再看看CounterServer2,可以看到其认可CounterServer3成为新leader的日志:

 

以上就是Counter演示程序的启动和选主流程简要过程,更多复杂的场景,比如网络分裂合并等,需要起更多的进程进行演示,可以自己试试。

下一篇将对这个过程,进行简单的源码流程阅读分析。

标签:选主,127.0,CounterServer1,SOFAJRaft,CounterServer3,0.1,源码,集群,leader
来源: https://blog.csdn.net/u014384625/article/details/122100990

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有