commit意味着什么

对于Server,意味着代码被执行。
对于Leader,意味着大多数Server已经执行。
RAFT中的COMMIT

需要明确的概念

我们首先需要来看看RAFT算法的一些定义。
这里面有两个需要注意的地方:

  1. commit是已经Server执行的代码。每一个server都有一个commitIndex作为commit的记录,也就是执行过的代码的Index。leader的commitIndex又叫leaderCommit。需要注意的是:Leader的commitIndex是当受到大多数节点成功日志复制后,才会更新的
  2. 每一个Server会维持一个LastLogIndex和LastLogTerm,作为与其他节点交流时,进行新旧比较的依据。

投票的过程

当Candidate发送给Follower RequestVote RPC请求后,Follower只会比较两个参数,一个是LastLogIndex,一个是LastLogTerm。只要这两个数据大于本地的数据,那Follower就会给对方投票。

问题来了!

RAFT中的COMMIT
接下来我们要分析这里出现的情况,在已有的算法基础上,会不会有问题呢?

  1. 在a阶段,S1作为Leader本地Commit了Log,并通过AppendEntries将信息发送给其他Server,其中S2收到信息并在本地Commit。

  2. 在b阶段,S1掉线,S5成为了Leader,这里接受到(S3,S4,S5)三者的投票。S5在任期3,Commit了Log后掉线。

  3. 在c阶段,S1重新进入集群,并被选为Leader,S3接受到LeaderS1的信息,在本地Commit了任期2的日志。

  4. 在d阶段,S5重新被选为Leader,这里为什么S5会被选了Leader呢?这是因为在进行投票时,Follower只会比较LastLogIndex和LastLogTerm,对于S5,这两个参数分别为2,和3。这样的话,他就可能会接收S2,S3,S4,S5四个人的投票。

而一旦S5成为了Leader,现在所有其他节点就会以S5任期3的Log为准。之前已经被大多数节点Commit的Log就会被覆盖。这就会导致不一致性,前面已经被大多数节点接收的内容,竟然会被覆盖?这也是问题所在。

那如何修复Raft算法呢? Raft在这里要求,Leader不允许Commit之前任期的Log。如果Leader想要执行之前任期的Log,他需要在新的任期里来执行。事实上,这个时候S1在任期2里面的日志,在他的记录里是没有Commit的,因此他很容易识别这个问题。

  1. 图中还有一个e阶段,这是正常的情况下,任期2时Leader就将大多数日志复制给别的节点,这个时候S5也不会被选为Leader,就不会出现之后的覆盖问题。

相关文章:

  • 2021-12-14
  • 2022-12-23
  • 2022-12-23
  • 2021-04-10
  • 2021-07-23
  • 2021-06-08
  • 2021-10-05
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-04-10
  • 2021-08-10
  • 2021-07-10
相关资源
相似解决方案