筏:日志清理和AppendEntries

时间:2016-05-15 09:49:21

标签: raft

日志清理会删除对当前状态没有贡献的条目,那么如果慢速关注者或新成员需要删除条目,如何构建AppendEntries?需要修改AppendEntries以便它可以包含非连续的条目吗?或者使用快照?

1 个答案:

答案 0 :(得分:2)

Copycat使用的算法实现了一种增量压缩形式,该算法与Raft dissertation中描述的日志清理算法有些类似。因此,有一些先例和代码来说明如何做到这一点。 Copycat的增量压缩算法与Raft文献中描述的算法的不同之处在于,它在压缩后保留日志中条目的位置,以利用顺序读取而不是将条目复制到日志的头部,但是AppendEntries RPC发送给关注者仍然可以在一批条目中发送差距。

我们只需在AppendRequest批次中包含每个条目的索引即可处理缺少的条目。但是这也需要日志中的某些机制来跳过关注者的条目。如果关注者从领导者日志的压缩片段接收条目,则关注者必须通过在将条目写入日志时跳过条目来复制领导者日志的结构。

Raft中的增量压实还存在一些其他挑战,这些挑战在Raft文献中没有广泛描述,特别是在处理墓碑方面。墓碑的一个问题是,在将它们应用于所有服务器之前,它们无法从日志中删除。如果提交了一个逻辑删除并且在将其复制到跟随者(可能被分区)之前从领导者的日志中删除了该逻辑删除,则该跟随者可能永远不会删除其状态。在Copycat中,这需要添加globalIndex来跟踪存储在所有服务器上的最高索引。

但是我离题了,我意识到我过分回答了你的问题。 Raft中的增量压实是一个有趣且具有挑战性的问题。如果您有兴趣阅读有关如何在Copycat中解决它的更多内容,我写了extensive documentation on the Copycat's incremental compaction algorithm,包括对处理墓碑的各种问题的深入描述以及在增量压缩算法之上实现快照的方法

如果您从Copycat的文档中学到一件事,那么Raft中的增量压缩可能会有很多复杂性。我们用了几个月的时间来计算出其中的所有算法,但也许我们学到的经验对你有用。

当然,在Raft中实现快照比使用Copycat中的增量压缩算法要容易得多。但它仍然存在一些复杂性。例如,Java不太适合在快照期间分配进程以防止阻塞,这也是我们选择为Raft编写增量压缩算法的原因之一。在Copycat中实现对大型快照的支持需要在内存中复制完整的状态机状态或添加领导者传输机制,以确保在快照大型状态机时不会阻止领导者。根据环境的实际情况权衡选项。