我对raft算法理解

179 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

定义

raft算法是故障容错算法(Crash Fault Tolerance,CFT)中的一种。
故障容错算法是解决分布式系统中存在存在故障,但不存在恶意攻击场景下的共识问题。 raft允许在n>2f+1(n为节点个数,f为故障节点个数)情况下的分布式共识。

raft算法动画

raft动画算法 可以从raft算法动画了解raft算法

包含流程

raft包含以下流程,后续会逐一详细介绍。

  • 初始化
  • 选举 Leader Election
  • 日志复制 LogReplication

节点状态

  • Follower state
  • Candidate state
  • Leader state

节点角色

不同状态的节点对应不同的角色

  • Follower (追随者)
  • Candidater (候选者)
  • Leader (领导者)

名词解释

term:任期,一个任期内只允许有一个leader。

流程

初始化

所有节点都处于follower state,term为0

选举

选举出主节点

  • 所有follower state的follower节点,会启动一个超时计时器随机超时时间为150~300ms,称之为election timeout,选举超时
  • 当超时时间到达,follower节点,会改变状态为candidate state,转变为candidator。
  • candidator,变更term任期,term自增,发起leader election。首先投自己一票。然后向其它follower发送投票申请。
  • 其它follower收到candidator投票申请后,若当前follower 在term内未投过票,则投candidator一票,返回响应给candidator。并且重置election timeout超时计时器
  • candidator收到半数以上投票响应后,转变状态为leader状态,变为leader角色。
  • leader会发送定时发送附加条目给所有follower节点,称之为hearebeat timeout心跳检测超时,follower返回心跳检测响应给leader。在未收到心跳检测期间,选举超时计时器就开始计时,收到心跳检测则重置超时计时器。

选举异常情况

  • 如果leader宕机,未发送心跳检测,follower 选举超时计时器超时时间到达,就会进行下一轮的选举,follower变成candiate state状态,重复上面的步骤。
  • 如果两个follower同时转变成candidate state且未收到半数以上的投票,则继续下一次超时,直到一个follower变成candidate state收到半数以上投票,成为leader

日志复制

通过日志复制,客户端请求操作在系统节点中达到共识。 客户端所有请求都经过leader。由leader转发给follower节点。

  • 客户端发送请求给leader,leader将请求操作写入日志,状态为未提交。
  • 在下一个心跳检测时,将请求操作转发给其它所有follower节点。
  • follower节点接受到请求操作,将操作写入日志,状态为未提交,并返回响应给leader节点。
  • leader节点收到半数以上请求,将本地日志提交,并返回客户端结果。同时在下一次心跳将提交请求发送给所有follower节点。
  • follower节点收到提交请求将日志提交。系统达到共识

日志复制异常情况

网络分区

假设有5个节点A,B,C,D,E,F。B为leader节点,其它为follower节点。当前term为1 当A和B分与C,D,E网络分区。 image.png

A和B,B是leader节点,并持续向A节点发送心跳,无需选举leader节点。
C、D、E由于在超时时间内,未收到leader节点心跳,因此会进行leader election,leader选举,同时term自增+1,term变为2。
假设C、D、E节点中节点E选举为leader节点。在两个分区内分别有一个客户端发送请求到分区内的leader节点。 image.png

在A和B分区内,客户端发送请求给leader节点B,B执行操作写入日志,状态为未提交。B将请求发送给分区内其它follower节点A,A节点返回响应,B收到响应,但由于节点个数是5个,B未收到半数以上的响应,因此不会进行提交操作。
而在C、D、E分区节点中,客户端发送请求给leader E,E执行操作写入日志,状态为未提交。E将请求发送给分区其它节点C、D,C、D响应给E,E收到半数以上响应(包括自己),进行提交操作,返回响应给客户端,并发送提交请求给其它节点,其它节点进行提交操作。
当网络恢复后,E和B两个leader节点分别发送心跳给其它所有节点,B和A节点发现更高的term,同步leader E的日志,并回滚自己节点未提交的日志。