raft-11-raft-simple raft协议的Java版本简单实现
2022年7月9日大约 6 分钟
前言
大家好,我是老马。
分布式系统中,一致性算法是最重要的基石,也是最难学习的部分。
本系列根据 jraft 作为入口,学习一下 raft 的原理和实现。
raft 系列
目的
这篇实现的设计写的比较清楚,值得学习。
https://github.com/DanielJyc/raft-simple
raft Java实现的详细设计文档
原文地址:https://www.yuque.com/aidt/tq712e/bhhyno
概述
第一期,只实现raft一致性算法的核心功能,先不实现集群成员变化、日志压缩等功能。
本文为raft实现的设计文档,对raft算法进行抽象,将关键逻辑用图形和表格梳理清楚,从而给使用Java代码进行实现提供设计文档。
主要概念
- server:服务器,可能为leader、candidate、follower中的任意一方
- leader:主节点
- candidate:候选节点
- follower:从节点
- RPC:远程过程调用,在这里指通信接口
- election:选举leader的过程
- client:客户端,发起请求,传输数据的使用方
- entry:条目,=term + 状态机指令(数据) + logIndex(日志索引)。
- term:任期号,即一个数字。如下图,多个term组成了整个生命周期的时间轴。

关键设计
领域模型
term介绍
核心的数据结构即为entry,多个entry组成了本地的数据模型,如下图:
- term:任期号
- index:日志索引,从1开始递增
- data:保存的数据
体现在一个集群中,则如下图:
整体模型

用例图

模块划分

关键类设计
整体类图如下

Server状态流转类图

server状态流转
备注:跟随者只响应来自其他服务器的请求。如果跟随者接收不到消息,那么他就会变成候选人并发起一次选举。获得集群中大多数选票的候选人将成为领导者。在一个任期内,领导人一直都会是领导人直到自己宕机了。
Entry状态转换
从客户端submit到最终apply到状态机:
核心实现流程
leader选举
follower投票
约束转换:
- 如果term currentTerm,那么就令 currentTerm 等于 T,并切换状态为跟随者(5.1 节)
candidate发起投票(广播)

candidate发起投票(单个)
通过ifLeaderChannel方式通知状态转换模块,由candidate转换为leader
日志复制
follower接受条目

leader请求条目(广播)
leader请求条目(单个)

客户端submit
接收客户端submit

客户端submit

提交过程:append-commit-apply-sm
append-commit-apply-sm概述

commit2Apply

状态机的一种实现(apply2sm)

server角色流转的详细实现
基于上面的server状态流转的状态机,详细描述如下:

实现参考
其他
通信模块
dubbo参考:
grpc参考:
参考资料
贡献者
binbin.hou