Lab 2D
lab 2D 是实现日志压缩的
assignment指示完成三个函数:Snapshot、CondInstallSnapshot和InstallSnapshot RPC
Snapshot
Snapshot函数是 上层与 raft来交互的,上层调用Snapshot函数来让leader进行snapshot。
这个函数有几个比较重要的rules :
如果 index <= lastSnapshotIndex ,那说明这个snotshop请求是过期的,可能由于各种网络原因之类的引起,这时候就要拒绝这个请求
要进行snapshot丢弃的日志,首先应该已经被 commit 且 apply了
需要持久化快照信息
CondInstallSnapshot
CondInstallSnapshot这个函数可以设计为永远只返回true
在向applyCh写入一条消息后,会调用CondInstallSnapshot()接口是用来判断是否可以实施快照的,比如判断一下快照的index是否小于节点的commitIndex。
如 config.go/applierSnap():
因为在 lab2B 实现中,往 applych发送log entry时是不持有锁的
因为教授说过,在发送 applych的时候不能持有锁。
上层实现时是在接收到一定的log entry 时进行snapshot,在snapshot返回时service不会进行任何操作,如果此时锁还在发送 log entry 的channel那里,进行 snapshot又需要获取锁,所以会造成死锁。
因此lab assignment选择让 log entry 和 snapshot 并发执行,这样子你就不能确定service什么时候能接收到snapshot了。
我们必须引入CondInstallSnapshot函数,确定service接收到snapshot的时间。
InstallSnapshot
InstallSnapshot 也有几个重要的规则:
如果 leader term 小于自己的term,就立刻拒绝
snapshot也相当于一次心跳,需要重置选举时间等心跳操作
如果发送过来的快照落后于当前已经应用的快照,那就直接拒绝
follower应用成功后需要更新 commitIndex 和 lastapplied
如果leader 发送snapshot成功,需要更新 发送给那个 server的对应的matchIndex和nextIndex
Last updated