在 RAFT 中,是否有可能对日志条目达成多数共识但该条目未提交?

In RAFT is it possible to have a majority consensus on a log entry but the entry is not committed?

考虑官方的这个模拟raft webpage

为什么 term 2 index 1 尽管 S2 (leader)S3S4 在日志上达成一致但仍未提交?我 运行 这几分钟来确保所有通信都已完成。

奇怪的是,如果我再添加一个日志条目 term 6 index 2 那么 term 2 index 1 将被提交。

有谁知道阻止 term 2 index 1 被提交的规则是什么?

您的领导在第 6 学期,但是 none 的日志条目来自第 6 学期;这会调用 Raft 中的特殊规则。领导者不会自动提交之前任期的条目,因为在某些情况下这样做是不安全的。第 5.3 节和第 5.4 节详细讨论了这一点(另请参见图 8)。

来自第 5.4.2 节:

To eliminate problems like the one in Figure 8, Raft never commits log entries from previous terms by counting replicas. Only log entries from the leader’s current term are committed by counting replicas; once an entry from the current term has been committed in this way, then all prior entries are committed indirectly because of the Log Matching Property. There are some situations where a leader could safely conclude that an older log entry is committed (for example, if that entry is stored on every server), but Raft takes a more conservative approach for simplicity

你的例子完美地展示了为什么这是不安全的。让我们假设 S2 提交 然后我们将通过将两件事提交到同一个槽中来打破它。

  1. S2 提交插槽 1(本地)。
  2. S2 发送AppendEntries(commitIndex=1, []).
  3. S3 接收并应用 AppendEntries(commitIndex=1)
    • 2 现在在两台主机上提交。
    • 其他主机没有收到消息。
  4. S1 被选为领导者
    • S1 is 'more up-to-date' than any other log (§5.4.1) and easily wins an election.
  5. S1 发送 AppendEntries([4])
    • 领导者做的第一件事就是让所有其他日志看起来像它自己的。
  6. S4 接收并应用 AppendEntries([4])
    • 这会覆盖插槽 1 的值 2
  7. S5 接收并应用 AppendEntries([4]).
  8. S1 在本地提交 4
    • 我们打破了它!! 两个承诺值
  9. S2,S3 收到并申请 AppendEntries([4])
    • 我们双重破坏了它,我们丢失了提交的数据!!
    • 优秀的工程师会在此处放置一个断言来捕获此覆盖。

发生什么事了?本质上,我们为同一个位置选出了两个不同的领导者。 (当 S1 更新时,S2 被选为领导者。)

那么为什么领导者在不等待后续请求的情况下提交自己任期的条目是安全的?因为不可能进入上述情况。让我们考虑两个节点 (S2, S1) 分别认为它们同时是第 2 项和第 3 项中的领导者的情况。如果 S2 准备好将 2 提交到插槽 1 中,那么大多数都具有相同的值。这意味着在插槽1中,没有任何多数人投票支持其他任何任期。

(顺便说一句,我花了一分钟时间才弄清楚你是如何陷入这种情况的。)

顺便说一句,Raft 是作为 "more understandable version of Paxos" 销售的。我不同意:它似乎有同样多(如果不是更多)这样的极端情况。但是,Raft 的作者真的很擅长让工程师很容易地正确实现一些实用的东西。这跟作者写Raft论文的方式有很大关系