在官方raft 网页中考虑这个模拟
为什么term 2 index 1
尽管没有提交S2 (leader)
,S3
并且S4
同意日志?我运行了几分钟以确保所有通信都已进行。
奇怪的是,如果我再添加一个日志条目term 6 index 2
,那么term 2 index 1
将被提交。
有谁知道阻止term 2 index 1
提交的规则是什么?
在官方raft 网页中考虑这个模拟
为什么term 2 index 1
尽管没有提交S2 (leader)
,S3
并且S4
同意日志?我运行了几分钟以确保所有通信都已进行。
奇怪的是,如果我再添加一个日志条目term 6 index 2
,那么term 2 index 1
将被提交。
有谁知道阻止term 2 index 1
提交的规则是什么?
你的领导在第 6 学期,但没有任何日志条目来自第 6 学期;这调用了 Raft 中的一个特殊规则。领导者不会自动提交上一个任期的条目,因为在某些情况下这样做是不安全的。第 5.3 节和第 5.4 节详细讨论了这一点(另请参见图 8)。
从第 5.4.2 节开始:
为了消除图 8 中的问题,Raft 永远不会通过计算副本来提交先前条款的日志条目。只有来自领导者当前任期的日志条目通过计算副本来提交;一旦以这种方式提交了当前术语中的条目,则由于日志匹配属性,所有先前的条目都将间接提交。在某些情况下,领导者可以安全地断定已提交较旧的日志条目(例如,如果该条目存储在每个服务器上),但 Raft 为简单起见采取了更保守的方法
您的示例完美地说明了为什么这是不安全的。让我们假设 S2确实提交了,然后我们将通过将两件事提交到同一个插槽来打破它。
AppendEntries(commitIndex=1, [])
.AppendEntries(commitIndex=1)
。
2
现在在两台主机上提交。AppendEntries([4])
.
AppendEntries([4])
。
2
在插槽 1 处的值。AppendEntries([4])
。4
本地
提交AppendEntries([4])
。
发生了什么?本质上,我们为同一个位置选出了两个不同的领导人。(当 S1 更新时,S2 被选为领导者。)
那么为什么领导者在不等待后续请求的情况下提交自己任期的条目是安全的?因为不可能进入上述情况。让我们考虑两个节点(S2,S1)分别在第 2 和第 3 项中认为它们同时是领导者的情况。如果 S2 准备好提交2
到插槽 1,那么大多数人在那里具有相同的值。这意味着在插槽1中,没有多数人投票赞成其他任期2
。
(顺便说一句,我花了一分钟才弄清楚你是如何陷入这种情况的。)
顺便说一句,Raft 被称为“更易于理解的 Paxos 版本”。我不同意:它似乎有同样多(如果不是更多)这样的极端案例。但是,Raft 作者真的很擅长让工程师轻松地正确实现一些实用的东西。这与作者如何撰写 Raft 论文有关。