领导者提交日志条目并在通知追随者此承诺之前崩溃时,raft 如何保持安全?

问题描述 投票:0回答:2

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

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

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

然而,请考虑以下复杂场景(摘自 PHD 论文“CONSENSUS:BRIDGING Theory And Practice”第 23 页)。

此时,第 2 学期的日志条目已复制到 大多数服务器,但未提交。如果 S1 崩溃 (d1),S5 可以被选为领导者(由 S2、S3 和 S4 投票)并且 用第 3 学期的条目覆盖条目。

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

根据我的理解,一个已提交的条目(应用于状态机并可能将结果告知客户)永远不会被覆盖?

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

谢谢。

distributed-computing distributed-system consensus raft
2个回答
6
投票

Raft中commit entry的条件更多了

这篇论文的第4页(Raft的1页摘要)它说

领导:

...

如果存在 N 使得 N > commitIndex,大多数 matchIndex[i] ≥ N,并且 log[N].term == currentTerm set 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包含所有提交的条目。候选人必须联系大多数集群 为了被选举,这意味着每个提交的条目必须存在至少在其中一个服务器中

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


0
投票

然而,新领导者拥有已提交的条目但不知道它应该提交它的情况仍然存在。

假设 S1 是旧领导者,Log1 附加到 S2 和 S3。此时,S1 知道是时候提交 Log1 了。 S1 在本地提交后立即崩溃。

现在 S2 上台并拥有 Log1,但它永远不会提交它,直到新的日志条目到达 S2,撞到 S2 的 commitIdx,最终应用 Log1。

© www.soinside.com 2019 - 2024. All rights reserved.