distributed - Raft 如何处理 AppendEntries RPC 中的延迟回复?

标签 distributed distributed-system consensus raft

我在阅读 Raft paper 时想到了一个问题.场景如下。有3个新启动的Raft实例,R1,R2,R3。 R1被选为leader,nextIndex为{1, 1, 1},matchIndex为{0, 0, 0},任期为1。现在它从客户端收到command 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},这是不正确的。当领导者发送下一个 AppendEntries RPC,即心跳或日志复制时,它可以修复 nextIndex,但 matchIndex 永远没有机会被修复。

我的解决方案是为每个单独的 RPC 调用向 AppendEntries 参数和结果添加一个序列号。但是,我想知道是否有一种方法可以只用论文给出的参数来解决这个问题,即不用序列号。

如有任何建议,我们将不胜感激,并提前致谢。

最佳答案

该协议(protocol)假定存在一些关于跟随者正在响应的 AppendEntries RPC 的上下文。因此,在某种程度上确实需要一个序列号(或更准确地说是一个相关 ID),无论是在协议(protocol)层、消息传递层还是在应用程序本身。领导者必须有某种方法将请求与响应相关联,以确定跟随者正在确认哪个索引。

但实际上还有一个不常被讨论的替代方案。 Raft 协议(protocol)的一些修改让追随者在响应中发送他们最后的日志索引。您还可以使用最后一个日志索引来确定哪些索引已保存在关注者上。

关于distributed - Raft 如何处理 AppendEntries RPC 中的延迟回复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56677690/

相关文章:

erlang - Erlang 中终止节点的检测是如何工作的? net_ticktime 如何影响 Erlang 中节点活跃度的控制?

Java:正确关闭多线程服务器的套接字

messaging - 逻辑时钟 : Lamport Timestamps

algorithm - BFT与PBFT与BA共识算法

distributed-system - 筏日志条目中的操作是否应幂等?

distributed - Raft 是如何线性化的?

networking - P2P应用程序如何找到其他节点?

distributed - MapReduce 是一种分析 http 服务器日志的好方法吗?

synchronization - 分布式客户端之间同步状态的方式

hadoop - 测试大数据框架需要什么环境?