考虑一下官方的这个模拟筏网页 https://raft.github.io/
Why is term 2 index 1
尽管没有承诺S2 (leader)
, S3
and S4
同意日志吗?我运行了几分钟以确保所有通信均已完成。
奇怪的是,如果我再添加一个日志条目term 6 index 2
then term 2 index 1
将致力于。
有谁知道阻止的规则是什么term 2 index 1
承诺?
您的领导者处于第 6 学期,但没有任何日志条目来自第 6 学期;这会调用 Raft 中的一个特殊规则。领导者不会自动提交前一学期的条目,因为在某些情况下这样做是不安全的。第 5.3 节和第 5.4 节详细讨论了这一点(另请参见图 8)。
从第 5.4.2 节:
为了消除如图8所示的问题,Raft
从不通过计数提交之前术语的日志条目
复制品。仅记录领导者当前的条目
术语通过计算副本来提交;一旦进入
从本届任期起一直以这种方式承诺,
那么所有先前的条目都是间接提交的,因为
日志匹配属性。有一些情况
领导者可以安全地得出结论,较旧的日志条目
已提交(例如,如果该条目存储在每个
服务器),但 Raft 采用了更保守的方法
为了简单起见
您的示例完美地说明了为什么这是不安全的。我们假设S2确实承诺然后我们将通过将两个东西提交到同一个槽中来打破它。
- S2 提交槽 1(本地)。
- S2发送
AppendEntries(commitIndex=1, [])
.
- S3 receives and applies
AppendEntries(commitIndex=1)
.
-
2
现在已提交到两台主机上。
- 其他主机不会收到该消息。
- S1 is elected leader
- S1 比任何其他日志都“更新”(第 5.4.1 节),并且很容易赢得选举。
- S1 sends
AppendEntries([4])
.
- 领导者做的第一件事就是让所有其他日志看起来像自己的日志。
- S4 receives and applies
AppendEntries([4])
.
- S5接收并申请
AppendEntries([4])
.
- S1 commits
4
locally
- S2,S3 receive and apply
AppendEntries([4])
.
- 我们已经双重破坏了它,我们丢失了提交的数据!
- 一个好的工程师会在这里放置一个断言来捕获这种覆盖。
发生了什么?本质上,我们为同一位置选举了两位不同的领导者。 (当 S1 更新时,S2 被选为领导者。)
那么为什么领导者可以安全地提交自己任期的条目而不等待后续请求呢?因为不可能出现上述情况。让我们考虑两个节点(S2、S1)分别在第 2 项和第 3 项中同时认为自己是领导者的情况。如果 S2 准备好提交2
进入槽 1,然后大多数在那里具有相同的值。这意味着没有多数人投票支持第 1 任期中的其他任何具有更高任期的任何事物。这意味着 S1 要当选为第 3 任期的领导者,必须有2
在插槽 1 中。
(顺便说一句,我花了一分钟才弄清楚你最初是如何陷入这种情况的。)
顺便说一句,Raft 被宣传为“Paxos 的更容易理解的版本”。我不同意:它似乎有同样多(如果不是更多)的极端情况,比如这些。但是,Raft 作者确实擅长让工程师轻松正确地实现一些实用的东西。这和作者如何写Raft论文有很大关系。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)