【问题标题】:How to handle reordered RPC in raft如何在 raft 中处理重新排序的 RPC
【发布时间】:2019-06-16 01:28:44
【问题描述】:

在实现 Raft 算法时,我发现有一种情况我认为可能对集群造成伤害,也可能不会。

假设一些来自 Leader 的 AppendEntriesRPC 被重新排序(网络延迟或其他原因)是合理的。考虑领导者使用prev_log_index = 1向对等点A发送心跳AppendEntriesRPC,然后发送另一个带有条目2的AppendEntriesRPC,然后它崩溃(我通过我的测试中的回调确保这立即发生)。如果两个 RPC 按发送顺序处理,则条目 2 将成功插入。但是,如果心跳 RPC 延迟,那么 peer A 会首先插入 entry 1 并响应 Leader。然后是延迟的心跳,peer A 将删除条目 2,因为该条目与 Le​​ader 的prev_log_index = 1 冲突。所以对等体 A 错误地删除了一个日志条目。

再深入一点,如果Leader没有立即崩溃,它会解决这个问题吗?我认为如果 peer A 正确响应延迟的心跳,Leader 会在以后的一些 RPC 中发现并修复它。

但是,如果对等体 A 对条目 2 的响应导致 commit_index 前进怎么办?在这种情况下,节点 A 投票将 commit_index 推进到 2,即使它实际上没有条目 2。因此可能没有足够的票数来推进这一推进。现在当Leader崩溃时,日志较少的节点将被选为Leader。我在测试过程中确实遇到过这种情况。

我的问题是:

  1. 我的推理正确吗?
  2. 如果重新排序 RPC 是一个真正的问题,我应该如何解决?对所有 RPC 进行索引和缓存,并强制它们一一处理是一个好的解决方案吗?我发现在 gRPC 中很难实现。

【问题讨论】:

    标签: distributed-computing distributed-system consensus raft


    【解决方案1】:

    Raft 假设一个有序的流协议,例如 TCP。也就是说,如果一条消息无序到达,那么它会被缓冲,直到它的前任到达。 (这种行为是 TCP 存在的原因:因为每个单独的数据包都可以通过服务器之间的单独路由,并且很有可能出现乱序消息,并且大多数应用程序更喜欢易于使用的严格排序。)

    其他协议,例如普通的旧 Paxos,可以处理乱序消息,但通常比 Raft 慢得多。

    【讨论】:

    • 有一些关于 gRPC 的解决方法吗?通过搜索,我发现 grpc 中的流式传输可能会有所帮助。有没有更好的解决方案?
    • 你好 Michael,通过一些实验我解决了重新排序的 gRPC 问题,谢谢。但是,我想知道您是否可以更深入地了解您为什么说 Raft 需要有序流?这是因为我发现 Raft 论文说“它们确保在所有非拜占庭条件下的安全性(从不返回错误的结果),包括网络延迟、分区、丢包、重复和重新排序。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    • 2017-01-05
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    相关资源
    最近更新 更多