Skip to content

DanielJyc/raft-simple

Repository files navigation

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组成了整个生命周期的时间轴。

image.png

关键设计

领域模型

term介绍

核心的数据结构即为entry,多个entry组成了本地的数据模型,如下图: image.png

  • term:任期号
  • index:日志索引,从1开始递增
  • data:保存的数据

体现在一个集群中,则如下图: image.png

整体模型

image.png

用例图

image.png

模块划分

image.png

关键类设计

整体类图如下

image.png

Server状态流转类图

image.png

server状态流转

image.png 备注:跟随者只响应来自其他服务器的请求。如果跟随者接收不到消息,那么他就会变成候选人并发起一次选举。获得集群中大多数选票的候选人将成为领导者。在一个任期内,领导人一直都会是领导人直到自己宕机了。

Entry状态转换

从客户端submit到最终apply到状态机: image.png

核心实现流程

leader选举

follower投票

image.png 约束转换:

  1. 如果term < currentTerm返回 false (5.2 节)
  2. 如果 votedFor 为空或者为 candidateId,并且候选人的日志至少和自己一样新,那么就投票给他(5.2 节,5.4 节)
  3. 如果接收到的 RPC 请求或响应中,任期号T > currentTerm,那么就令 currentTerm 等于 T,并切换状态为跟随者(5.1 节)

candidate发起投票(广播)

image.png

candidate发起投票(单个)

image.png 通过ifLeaderChannel方式通知状态转换模块,由candidate转换为leader

日志复制

follower接受条目

image.png image.png

image.png

leader请求条目(广播)

image.png image.png image.png

leader请求条目(单个)

image.png

客户端submit

接收客户端submit

image.png

客户端submit

image.png

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

append-commit-apply-sm概述

image.png

commit2Apply

image.png

状态机的一种实现(apply2sm)

image.png

server角色流转的详细实现

基于上面的server状态流转的状态机,详细描述如下: image.png

实现参考

MIT 6.824 2020 Raft 实现细节汇总

其他

通信模块

dubbo参考:

grpc参考:

Releases

No releases published

Packages

No packages published

Languages