我在阅读Raft 论文时提出了一个问题。剧情如下。有 3 个新启动的 Raft 实例,R1、R2、R3。R1被选举为leader,nextIndex {1, 1, 1},matchIndex {0, 0, 0}和term 1。现在它接收到来自客户端的命令1,实例的日志如下:
R1: [index 0, command 0], [index 1, command 1]
R2: [index 0, command 0]
R3: [index 0, command 0]
如果网络不可靠怎么办?如果 R1 正在向 R2 发送此日志,但 AppendEntries RPC 超时,则领导者 R1 必须再次重新发送 [index 1, command 1]。然后它可能会收到两次回复{term: 1, success: true}。
论文说:
If last log index ≥ nextIndex for a follower: send AppendEntries RPC with log entries starting at nextIndex
• If successful: update nextIndex and matchIndex for follower (§5.3)
• If AppendEntries fails because of log inconsistency: decrement nextIndex and retry (§5.3)
所以leader R1会增加nextIndex和matchIndex两次:nextIndex {1, 3, 1},matchIndex {0, 2, 0},这是不正确的。当leader发送下一个AppendEntries RPC,即心跳或日志复制时,它可以修复nextIndex,但matchIndex永远没有机会被修复。
我的解决方案是为每个单独的 RPC 调用添加一个序列号到 AppendEntries 参数和结果中。但是,我想知道是否有一种方法可以仅使用论文给出的参数来解决这个问题,即没有序列号。
任何建议将不胜感激,并提前感谢您。