对Raft的一点理解

根据Raft作者Diego Ongaro的课件整理

[论文](https://pdos.csail.mit.edu/6.824/papers/raft-extended.pdf)

按照课件的讲述顺序,理解raft

**Server States(状态)**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808145041729.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

cluster成员的状态有三种:

1. Leader:管理与CLient的交互;同一term中最多存在一个Leader

2.  Follower:接收Leader领导,无法发出请求,只能进行响应

3. Candidate:Leader的候选,若选举成功则成为Leader

**Term**

![在这里插入图片描述](https://img-blog.csdnimg.cn/2019080814593688.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

- Term分为选举期与正常工作期

- 一个Term中至多有一个Leader(可以没有 即选举失败了)

- 每个成员都保留Term的值,可以利用其识别过期的信息

**Heartbeats and Timeouts**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808151624488.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

  集群的初始状态下所有成员都是Follower,Follower要求每隔一段时间(几百ms左右)都能从Candidate或者Leader获取RPCs。

  所以Leader必须每隔一段时间就要发送一个heartbeat(empty AppendEntries RPCs),以保持Leader的地位。

  如果一个Follower在Timeout时间内没有接收到RPCs,那么这个Follower会认为Leader已经失效,这个Follower会变成Candidate并启动新一轮选举。

**Election Basics**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808152531536.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

  当启动新一轮选举后,首先Term + 1,Follower变为Candidate并投票给自己。然后Candidate会向其他所有的成员发送RequestVote RPC。

  如果Candidate接收到大多数成员的投票,那么Candidate变成Leader并向其他所有成员发送AppendEntry heartbeat

  如果接收到来自有效Leader的RPC那么Candidate重新变为Follower

  如果没有Leader产生则Term+1继续新的一轮

**Property :Safety and Liveness**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808153921331.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

Safety:每个成员只会进行一次投票,投给当前Term中第一次接收到的RequestVote RPC的源,并将投票保存在本地,这就保证了至多只有一个candicate可能得到majority

Liveness:为了防止无休止的选举,每个成员的election timeout时间在[T,2T]之间取随机,以此保证不会所有的follower同时发起选举,这个方法在RequestVote传播的时间远小于T时非常有效。

**Log Structure**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808160943431.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

- Log中保存Term和命令信息,使用index索引

- Log保存在稳定存储设备上,有利于故障恢复

- 如果命令在多数成员上commit那么就认为此命令成功commit,如图中index 1-7

**Normal Operation**

![在这里插入图片描述](https://img-blog.csdnimg.cn/2019080816285451.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

正常工作的流程:

1.client发送命令给leader

2.leader将命令加入自己的Log并发送AppendEntry RPC给follower

3.如果大多数成员response ok 那么就认为当前命令已经执行成功,Leader会response ok to client,并且会发送appendEntry通知follower在本地commit

- Leader会不断send message to crashed and slow follows

**Log Consistency**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808164006296.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

- raft通过唯一的 index和term组合 来唯一确定一条命令

- 不同的机器上在 相同的 index和term组合 之前的Log全部相同

- 当前位置的Log如果已经Commit,那么它前面的Log也已经Commit

**AppendEntry Consistency Check**

![在这里插入图片描述](https://img-blog.csdnimg.cn/2019080817030136.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

  每个AppendEntry RPC中都会保存前一个RPC使用的term和index,这使得一致性检测成为可能。对于Follower,只有当一个AppendEntry RPC保存的前一个term 与 前一个index 都与follow匹配时,follow才接受这个RPC并返回成功响应。

  这个特性保证了,只要follow接受AppendEntry RPC了,就说明在Follower中当前位置前面的Log与Leader完全匹配

**Leader Changes**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808171911478.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

  在leader变化后,clean up Log不应该立即进行,因为有些机器可能是crash的,如果一直等待恢复 来进行clean up会严重影响性能。clean up 应该放到Normal operation中进行。

  在Normal operation中converge log的方法是,假设Leader拥有的Log永远是正确的,所以Leader的工作就是让Follower的Log与Leader的Log能够match

  那么在Normal operation中如何实现converge的呢。我们知道只有那些commit的数据是有效的,未commit的数据的情况client是不知道的,所以我们只需要关心commit的数据,具体方法?

**Safety Requirement**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808182103593.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

- Leader曾经commit过的Log必须在之后的所有Leader中出现

  要实现这一点可以限制commit或者限制选举?

**Pick The Best Leader**

![在这里插入图片描述](https://img-blog.csdnimg.cn/2019080818521132.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

通过在Candidate中选择最完整的“most complete”来保证commit的log都在新leader中

**Committing Entry from Current Term**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808185529123.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

**Committing Entry from Earlier Term**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808185958539.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

上图中若s5当选,如果按照原来的commit规则,已经commit的黄色的2会丢失。所以我们需要修改commit规则

**New rule**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808193001292.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

只有在Leader领导的term中出现commit后,以前的term中的log才可以提交commit

**Log Inconsistencies**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808193618564.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

Leader的目的将一直是补上上图中的缺口,删除extra的部分,即Repair?

**Repair Follower Logs**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808194412676.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

一开始设置相同的nextIndex,如果失败就-1,然后继续匹配,直到寻找到合适的nextIndex,然后按照每个成员特有的nextIndex发送appendEntry RPC

**!**

![在这里插入图片描述](https://img-blog.csdnimg.cn/201908081955058.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

一旦某个位置重写,那么当前位置后的就全部删除

**Neutralize Old Leader**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808200117155.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

对于old leader的处理?

**与client的交互**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808201150472.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808201211743.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

**系统配置相关**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808202251500.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

![在这里插入图片描述](https://img-blog.csdnimg.cn/2019080820290098.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

?更新配置时的延迟导致出现不同的majority

所以需要用2-phase解决

distributed decision 需要2-phase解决

**使用2-phase**

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808203158891.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

raft将第一个阶段作为中间阶段叫做:joint consensus,在这个阶段old configuration 和 new configuration都使用,commit和election必需分别在old cluster和new cluster 中都获得majority

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190808224524172.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poYWlxaW1pbmcyMDEw,size_16,color_FFFFFF,t_70)

**end!**

你可能感兴趣的:(对Raft的一点理解)