首页 > 解决方案 > 当领导者提交日志条目并在通知跟随者该承诺之前崩溃时,raft如何保持安全?

问题描述

在我的理解中,leader 向 follower 发送 AppendEntries RPC,如果大多数 follower 返回成功,leader 将提交该条目。它将通过将这个条目应用到自己的状态机来提交,并且它也会返回给客户端,让客户端知道命令成功。

但是,此时,追随者还不知道这一承诺。它将在下一个 AppendEntries(或心跳)RPC 调用中通知关注者。

在最简单的情况下,如果leader在commitment之后和下一个AppendEntries之前崩溃,raft会使用“只有最新的follower才能获胜”的策略来确保下一个leader必须包含这个日志条目(虽然没有提交),并且新的领导者将提交此条目并将 AppendEntries 发送给其他追随者。这样,日志条目就被安全地保存了。

但是,请考虑以下复杂情况(摘自 PHD 论文“共识:桥接理论与实践”第 23 页)。

在此处输入图像描述

此时,第 2 期的日志条目已在大多数服务器上复制,但尚未提交。如果 S1 像 (d1) 中那样崩溃,S5 可以被选举为领导者(来自 S2、S3 和 S4 的投票)并用它自己的第 3 期条目覆盖条目。

如果此时,它已在服务器 S1 中提交,但尚未在其他服务器中提交,该怎么办?如果 S1 然后像 (d1) 那样崩溃,这个日志条目会被 S5 覆盖吗?

在我的理解中,一个提交的条目(应用于状态机并可能通知客户端结果)永远不会被覆盖?

我对 raft 协议有什么误解吗?

谢谢。

标签: distributed-computingdistributed-systemconsensusraft

解决方案


Raft 中有更多的条件来提交条目。

本文的第 4页(筏的 1 页摘要)它说

领导:

...

如果存在 N 使得 N > commitIndex,则 matchIndex[i] ≥ N 的大多数,并且 log[N].term == currentTerm 设置 commitIndex = N(§5.3,§5.4)。

换句话说,不仅条目必须被复制到多数,它的任期也必须来自当前任期。这就是为什么在一个实际的系统中,一个新的领导者会提出一个 no-op,以便它可以推进这个 commitIndex。

所以现在我们知道领导者在那之前不会提交,但是如果它提交但不发送提交怎么办。

稍后在同一篇论文的第 5.4.1 节中它说(强调我的):

Raft...guarantees that all the committed entries from previous terms are present on each new leader from the moment of its election....Raft uses the voting process to prevent a candidate from winning an election unless its log contains all committed entries. A candidate must contact a majority of the cluster in order to be elected, which means that every committed entry must be present in at least one of those servers.

简而言之,根据定义,新领导者必须具有旧领导者认为已提交的条目。


推荐阅读