raft Java实现的详细设计文档

概述

本文章只实现raft一致性算法的核心功能:leader选举、日志复制,不包括集群成员变化、日志压缩等功能。主要目的适用于学习;
本文为raft实现的设计文档,对raft算法进行抽象,将关键逻辑用图形和表格梳理清楚,从而给使用Java代码进行实现提供设计文档。
实现代码GitHubhttps://github.com/DanielJyc/raft-simple

主要概念

  • server:服务器,可能为leader、candidate、follower中的任意一方
  • leader:主节点
  • candidate:候选节点
  • follower:从节点
  • RPC:远程过程调用,在这里指通信接口
  • election:选举leader的过程
  • client:客户端,发起请求,传输数据的使用方
  • entry:条目,=term + 状态机指令(数据) + logIndex(日志索引)。
  • term:任期号,即一个数字。如下图,多个term组成了整个生命周期的时间轴。

raft Java实现的详细设计文档

关键设计

数据结构模型(领域模型)

term介绍

核心的数据结构即为entry,多个entry组成了本地的数据模型,如下图:
raft Java实现的详细设计文档

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

体现在一个集群中,则如下图:
raft Java实现的详细设计文档

整体模型

raft Java实现的详细设计文档

用例图

raft Java实现的详细设计文档

模块划分

raft Java实现的详细设计文档

关键类设计

整体类图如下

raft Java实现的详细设计文档

Server状态流转类图

raft Java实现的详细设计文档

server状态流转

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

Entry状态转换

从客户端submit到最终apply到状态机:
raft Java实现的详细设计文档

核心实现流程

leader选举

follower投票

raft Java实现的详细设计文档
约束转换:

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

candidate发起投票(广播)

raft Java实现的详细设计文档

candidate发起投票(单个)

raft Java实现的详细设计文档
通过ifLeaderChannel方式通知状态转换模块,由candidate转换为leader

日志复制

follower接受条目

raft Java实现的详细设计文档
raft Java实现的详细设计文档


raft Java实现的详细设计文档

leader请求条目(广播)

raft Java实现的详细设计文档
raft Java实现的详细设计文档
raft Java实现的详细设计文档

leader请求条目(单个)

raft Java实现的详细设计文档

客户端submit

接收客户端submit

raft Java实现的详细设计文档

客户端submit

raft Java实现的详细设计文档

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

append-commit-apply-sm概述

raft Java实现的详细设计文档

commit2Apply

raft Java实现的详细设计文档

状态机的一种实现(apply2sm)

raft Java实现的详细设计文档

server角色流转的详细实现

基于上面的server状态流转的状态机,详细描述如下:
raft Java实现的详细设计文档

实现参考

MIT 6.824 2020 Raft 实现细节汇总