SOFAJRaft研究
侧边栏壁纸
  • 累计撰写 25 篇文章
  • 累计收到 11 条评论

SOFAJRaft研究

zhenxi
2023-09-20 / 0 评论 / 86 阅读 / 正在检测是否收录...

1 SOFAJRaft是什么?

Scalable Open Financial Architecture Stack 是蚂蚁金服自主研发的金融级分布式架构,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。

SOFAJRaft 是一个基于 Raft 一致性算法的生产级高性能 Java 实现,适用于高负载低延迟的场景。SOFAJRaft 是从百度的 braft 移植而来,做了一些优化和改进。

GitHub 地址:https://github.com/sofastack/sofa-jraft

文档地址:https://www.sofastack.tech/projects/sofa-jraft/overview/

SOFAJRaft笔记:https://www.yuque.com/huarou/gd4szw/zon6t9

2 SOFAJRaft用户

此处列出了已知在生产环境使用了 SOFAStack 全部或者部分组件的公司或组织。以下排名不分先后:

蚂蚁集团网商银行恒生电子数立信息Paytm天弘基金中国人保信美相互南京银行民生银行重庆农商行中信证券富滇银行挖财拍拍贷OPPO金融运满满译筑科技杭州米雅信息科技邦道科技申通快递深圳大头兄弟文化烽火科技亚信科技成都云智天下科技上海溢米辅导态赋科技风一科技武汉易企盈极致医疗京东小象生鲜北京云族佳欣亿云网山东网聪深圳市诺安赛威上扬软件长沙点三网易云音乐虎牙直播中国移动无纸科技黄金钱包独木桥网络wueasy北京攸乐科技易宝支付威马汽车亿通国际新华三klilalagroup

3 SOFAJRaft设计图

3.1 一个节点内部设计

v2-353092edc49c7fba0b92b0ef1508119d_b

①Node:Raft 分组中的一个节点,连接封装底层的所有服务,用户看到的主要服务接口,特别是 apply(task)用于向 raft group 组成的复制状态机集群提交新任务应用到业务状态机。

②存储:上图靠下的部分均为存储相关。

a.Log 存储,记录 Raft 用户提交任务的日志,将日志从 Leader 复制到其他节点上。

LogStorage 是存储实现,默认实现基于 RocksDB 存储,你也可以很容易扩展自己的日志存储实现;
LogManager 负责对底层存储的调用,对调用做缓存、批量提交、必要的检查和优化。

b.Metadata 存储,元信息存储,记录 Raft 实现的内部状态,比如当前 term、投票给哪个节点等信息。

c.Snapshot 存储,用于存放用户的状态机 snapshot 及元信息,可选:
SnapshotStorage 用于 snapshot 存储实现;
SnapshotExecutor 用于 snapshot 实际存储、远程安装、复制的管理。

③状态机:

  • StateMachine:用户核心逻辑的实现,核心是 onApply(Iterator) 方法, 应用通过 Node#apply(task) 提交的日志到业务状态机;
  • FSMCaller:封装对业务 StateMachine 的状态转换的调用以及日志的写入等,一个有限状态机的实现,做必要的检查、请求合并提交和并发处理等。

④复制:

  • Replicator:用于 Leader 向 Followers 复制日志,也就是 Raft 中的 AppendEntries 调用,包括心跳存活检查等;
  • ReplicatorGroup:用于单个 Raft group 管理所有的 replicator,必要的权限检查和派发。

Node 代表了一个 SOFAJRaft Server 节点,这些方框代表他内部的各个模块,我们用银行账户系统举例来说明 SOFAJRaft 的各模块是如何工作的。

⑤RPC:RPC 模块用于节点之间的网络通讯

  • RPC Server:内置于 Node 内的 RPC 服务器,接收其他节点或者客户端发过来的请求,转交给对应服务处理;
  • RPC Client:用于向其他节点发起请求,例如投票、复制日志、心跳等。

⑥KV Store:

  • KV Store 是各种 Raft 实现的一个典型应用场景,SOFAJRaft 中包含了一个嵌入式的分布式 KV 存储实现(SOFAJRaft-RheaKV)。

使用银行账户系统举例来说明 SOFAJRaft 的各模块是如何工作的。

当 Client 向 SOFAJRaft 发来一个“存 100 元”的命令之后,Node 的 Log 存储模块首先将这个命令以 Log 的形式存储到本地,同时 Replicator (复制器)会把这个 Log 复制给其他的 Node,Replicator 是有多个的,集群中有多少个 Follower 就会有多少个 Replicator,这样就能实现并发的日志复制。当 Node 收到集群中半数以上的 Node 返回的“复制成功” 的响应之后,就可以把这条 Log 以及之前的 Log 有序的送到状态机里去执行了。状态机是由用户来实现的,比如我们现在举的例子是银行账户系统,所以状态机执行的就是账户金额的借贷操作。如果 SOFAJRaft 在别的场景中使用,状态机就会有其他的执行方式。

Meta Storage(元存储) 是用来存储记录 Raft 实现的内部状态,比如当前 Term 、投票给哪个节点等信息。

Snapshot 是快照,所谓快照就是对数据当前值的一个记录,Leader 生成快照有这么几个作用:

  1. 当有新的 Node 加入集群的时候,不用只靠日志复制、回放去和 Leader 保持数据一致,而是通过安装 Leader 的快照来跳过早期大量日志的回放;
  2. Leader 用快照替代 Log 复制可以减少网络上的数据量;
  3. 用快照替代早期的 Log 可以节省存储空间。

3.2 三副本的架构图

刚才是一个节点内部的情况,那在 Raft Group 中至少需要 3 个节点,所以这是一个三副本的架构图。

v2-09c6a3993e837e0b47a86804ad3847e8_r

4 运行SOFAJRaft Counter 例子

4.1 启动客户端

image-20230920205958418

程序终止:

Usage : java com.alipay.sofa.jraft.example.counter.CounterServer {dataPath} {groupId} {serverId} {initConf}
Example: java com.alipay.sofa.jraft.example.counter.CounterServer /tmp/server1 counter 127.0.0.1:8081 127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083

image-20230920210026572

配置运行:

/tmp/server1 counter 127.0.0.1:8081 127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083

image-20230920204703098

启动节点1之后日志信息中出现报错,发现是连接不上8082、8083节点。

image-20230920204856066

在IDEA的Run/Debug Configuration中启动多实例运行:

image-20230920205105072

image-20230920204758759

配置节点二,节点三:

image-20230920205321799

image-20230920210012605

4.2 启动服务端

启动后终止程序:

Usage : java com.alipay.sofa.jraft.example.counter.CounterClient {groupId} {conf}
Example: java com.alipay.sofa.jraft.example.counter.CounterClient counter 127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083

增加配置:

image-20230920210700624

运行结果:

image-20230920210853311

4.3 查看生成日志

image-20230921090959600

生成日志目录:

image-20230921091449914

log目录:

image-20230921092826868

image-20230921092924624

image-20230921093100952

meta目录:

image-20230921093312918

记录 Raft 实现的内部状态,比如当前 term、投票给哪个节点等信息。

image-20230921093507988

snapshot目录:

__raft_snapshot_meta:快照数据。

data:最后一个共识的数据。

image-20230921093816616

5

评论 (0)

取消