raft-simple
raft-simple copied to clipboard
raft协议的Java版本简单实现
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返回 false (5.2 节)
- 如果 votedFor 为空或者为 candidateId,并且候选人的日志至少和自己一样新,那么就投票给他(5.2 节,5.4 节)
- 如果接收到的 RPC 请求或响应中,任期号T > 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参考: