在实施Raft算法时,我发现有一种情况可能会对集群造成伤害,也可能不会造成伤害。
可以合理地假设接收到来自Leader的一些AppendEntriesRPC已重新排序(网络延迟或其他原因)。考虑领导者使用prev_log_index = 1
向对等方A发送心跳AppendEntriesRPC,然后使用条目2发送另一个AppendEntriesRPC,然后崩溃(我确保通过测试中的回调立即发生这种情况)。如果按照发送的顺序处理这两个RPC,则将成功插入条目2。但是,如果心跳RPC延迟,则对等方A将首先插入条目1并响应Leader。然后出现延迟的心跳,对等体A将删除条目2,因为该条目与领导者的prev_log_index = 1
冲突。因此,对等体A会错误地删除日志条目。
要更深入一点,如果Leader不会立即崩溃,它将解决此问题吗?我认为,如果同级A对延迟的心跳正确响应,则Leader将找出并在以后的RPC中进行修复。
但是,如果同级A对条目2的响应导致commit_index
前进,该怎么办?在这种情况下,对等体A投票将commit_index
推进到2,即使它实际上没有条目2。因此,对于该推进而言,可能没有足够的投票。当领导者现在崩溃时,日志较少的节点将被选为领导者。而且我在测试过程中确实遇到了这种情况。
我的问题是:
答案 0 :(得分:0)
筏假定有序的流协议,例如TCP。就是说,如果消息到达的顺序不正确,则将其缓冲直到其前身到达。 (此行为是存在TCP的原因:因为每个单独的数据包都可以通过服务器之间的单独路由,并且出现乱序消息的可能性很高,并且大多数应用程序更喜欢轻松执行严格的排序。) / p>
其他协议(例如普通的旧Paxos)可以处理乱序消息,但通常比Raft慢得多。