Raft实现报告(16)
日志压缩
Raft的日志在正常运行时会随着时间的增长而变得越来越庞大,但在实际系统中,他不能无限制的增长。随着日志变长,他会占用过多的空间,并且需要更长的时间去做查找。如果没有某种机制来丢弃日志,这也会导致可用性的问题。
Snapshot
快找时最简单的压缩方法。在快照中,整个当前状态被写入稳定的存储上。存储完毕之后,丢弃到该点的整个日志。ZooKeeper中就使用了快照,本节的其余部分将会描述Raft中应用的快照。
还有些增量的压缩方法,例如日志清理,和日志结构合并树,也是可能的。他们每次对一小部分数据进行操作,因此他们会随着时间的推移更均匀的分布压缩负载。他们首先选择一个已经积累了许多删除和覆盖的对象数据区域,然后他们会更加紧凑的重写该区域中的活动对象并释放该区域。与快照相比,这需要显著的额外机制和复杂性,快照始终通过对整个数据集进行操作来简化问题。虽然日志清理需要对Raft进行修改,但是状态机可以使用与快照相同的接口来实现LSM树。
服务器将其日志中已提交的条目(索引 1 到 5)替换为新快照,该快照仅存储当前状态(本示例中的变量 x 和 y)。 快照最后包含的索引和term用于将快照定位在条目 6 之前的日志中。
上图展示了Raft快照的基本思想。每个服务器独立拍摄快照,仅覆盖其日志中已经提交的条目。大部分的工作包括状态机会将其当前状态写入快照。Raft还在快照中包含了少量的元数据:最后包含的索引时快照替换的日志中最后一个条目的索引(状态机应用的最后一个条目),最后包含的术语是此条目。保留这些内容以支持快照后第一个日志条目的AppendEntires一致性检查,因为该条目会需要先前的日志索引和term的索引,为了应对集群成员的状态变更,快照还在日志中包含了截止最后包含索引的最新配置。一旦服务器完成了写入快照,他可能会删除所有的日志条目,知道最后包含的索引,以及先前的任何快照。