我目前正在自己实现 Raft 共识算法,我遇到了以下问题。考虑有 4 个节点(A、B、C 和 D),因此可以提交超过 2 票的日志条目。现在我们启动集群并让 Leader A 用term = 0
. 然后发生以下事情:
- 从动 B/D 断开。
- 领导者 A 创建
LogEntry
X。 - 领导者 A 尝试复制到所有节点并最终失败,因为只有 2 个节点(A 和 C)。
- 节点 B 重新连接并超时,它使用 new 开始选举
term = 1
。 - 节点 A 失去了领导地位,因为它收到了节点 B 的
RequestVote
RPC。 - Node B can't win the election, because it has no
LogEntry
X. So there are no Leader in the cluster. - 节点A超时,再次被选为Leader。
- Leader A 成功将 X 复制
LogEntry
到 B。 现在节点 A/B/C 具有完全相同的
LogEntry
X,即(index = 0, term = 0)
. 然而,根据 Raft 论文,Leader A 不能提交 X,尽管它是自己生成的,并且多数同意 X。Raft 永远不会通过计算副本来提交先前条款的日志条目。只有来自领导者当前任期的日志条目通过计算副本来提交;
- 假设不再有
LogEntry
来自客户端的 s 来复制,所以LogEntry
X 保持未提交。
我的问题是:
- 这是一个真正的问题吗?
- 有一些解决方案吗?事实上,已经有一些关于 SoF 的帖子强调了这条规则的重要性。在这篇文章中,似乎说我们可以创建 X 的副本 Y,并复制 Y。它是否有效,或者是否存在通用解决方案?