1. 为什么需要checkpoint
状态机是通过由PhxPaxos选出的有序Chosen value(PaxosLog)系列进行状态转移得到的,而这些状态本质上也是一堆数据,但是这堆数据是由开发者自己进行维护的,我们不能要求开发者在这份数据上时刻做到极其严格的正确性, 那么这份数据很有可能因为机器的一些异常或者重启导致丢失,从而影响了数据的正确性。
所以我们的做法是只相信自己的数据,于是乎每次启动(RunNode
)的时候都会从0开始将所有的PaxosLog重新输入状态机(重演),从而保证状态机数据的完整性。但这个做法缺陷是非常明显的,第一:PaxosLog是无限增长的,每次都重新遍历,重启效率必然很低。第二:由于每次都要遍历,那么这些数据无法删除,从而要求无限的磁盘空间,这是无法做到的。
在分布式系统中,很多时候都需要checkpoint。
2. 从状态机的checkpoint来启动phxpaxos
Checkpoint的出现用于解决这个问题。我们不能要求开发者做到时刻的状态机数据正确,但要求开发者生成一个状态机的Checkpoint的时候,这份数据必须是正确的完整的。一个Checkpoint代表着一份某一时刻被固化下来的状态机数据,它通过sm.h
下的StateMachine::GetCheckpointInstanceID()
函数反馈它的精确时刻,于是每次启动的重演,我们只需要从这个时刻所指向PaxosLog位置开始而不是从0开始。下图描述了这一过程:
3. 控制PhxPaxos删除PaxosLog
有了一份Checkpoint,我们即可完成PaxosLog的删除,因为StateMachine::GetCheckpointInstanceID()
之前的PaxosLog都是不再需要的了。
4. 自动传输Checkpoint到其他节点
在没有Checkpoint的情况下,节点之间数据的对齐只需要进行PaxosLog的Learn即可,而加入了Checkpoint,则需要一个Checkpoint+PaxosLog的数据对齐。PaxosLog的对齐是有PhxPaxos自动完成的,但Checkpoint数据是掌握在开发者手里的,所以我们需要sm.h
里面一些函数来协助我们获取这些数据,以完成一个Checkpoint+PaxosLog的自动数据对齐。
下图展示一个自动对齐数据的流程:
![](https://github.com/tencent-wechat/phxpaxos/raw/master/doc/images/transfer_checkpoint_automatic.jpg)