2021 MIT 6.824 Lab2D Raft算法(四):日志压缩(log compaction)【完】

0 前言

经过前面三个lab我们实现了raft算法的选举(leader election)、日志复制(log replication)与持久化(persist)的功能,在最后一个lab将实现日志压缩(log compaction)。日志压缩的诞生出于这样的考虑:在我们前面所有的代码中,日志均存在内存里,然而如果一台服务器是24 × \times × 7地工作,某些时刻日志将会把内存撑爆,而且日志很多的话,持久化的时候也需要很多的IO操作时间,所以要引入日志压缩技术让服务器丢弃一些日志节省内存。所以使用什么技术丢弃日志是这一节讨论的话题。

1 Snapshot快照

raft使用的是Snapshot快照技术(论文第七章)。服务器在完成日志的apply之后,可以将快照信息写入快照(最后一条日志的Index和Term等),然后将此日志和之前的所有日志删除,节省内存的目的也就达到了。
由于快照是服务器自己独立进行的,由上层service命令raft执行。有时候会引出一些问题,比如leader在调用快照之后,删除了一些日志,但是某一Follower落后leader太多,需要向其发送的日志已经不在leader的内存里了。对于这种情况,raft的解决方案是leader直接发送自己的快照过去,让follower根据快照修改自己的状态。
快照技术简洁有效,需要注意的是创建快照的时机,创建频率太高(浪费磁盘带宽)或者太低(占用内存高)都不好。一种方法是日志到达一定数目的时候创建快照。当然这个问题在本lab里不会涉及。

2 接口设计

Raft论文比较简洁,没有对实现快照的函数接口做一个规定,lab2d为我们提供了几个接口,让我们分析一下。

2.1 Snapshot()接口

Snapshot接口是由上层service调用让raft节点来创建一个快照,接口有两个参数:

  1. index int,这个参数是快照的截止index
  2. snapshot []byte,上层service传来的快照字节流,将会包含所有截止到index的信息

如果说raft节点上次创建快照的时刻lastSnapshotIndex大于index,会拒绝创建快照,否则创建快照。

2.2 RPC调用接口

之前说过当一个follower落后leader太多时,leader会发快照过去。在我的实现中,当leader发现一个follower的nextIndex[follower]小于leader节点的快照时刻时,就会通过RPC调用发快照过去。所以还要设计两个调用接口:

  1. sendSnapshotToPeer(server int) 这个接口由leader调用发送快照
  2. InstallSnapshot(args *InstallSnapshotArgs,reply *InstallSnapshotReply),这个是RPC调用接口,参数在论文中有详细讲述。当follower决定接受快照之后,会像applyCh写入一条消息根据快照修改自己的状态。

有些读者对这个过程不太清楚,我这里举个例子
读者提问:有些follower落后太多,但是需要的日志leader已经删除了,这种情况怎么办?
答:这种情况leader发送将自己的 状态 拍成快照发送给follower(快照不是日志,是状态)。举个例子(lab3中会涉及),在一个key/value存储系统中,leader收到了多条日志,x = 3,x=4,x=5,x=6,leader向follower复制日志,然后不停commit修改了x的值,每次修改后删去日志。但是某个follower网络有故障,一直没复制到日志,等到leader提交x=6之后才上线。leader发送心跳后发现此follower落后太多,于是直接将x=6这个状态写成快照,发送给follower,让它安装(需要额外RPC),follower收到快照,在自己的状态中直接修改x=6,并且将自己与leader的日志匹配位置修改到x=6的日志index处。

2.3 CondInstallSnapshot()接口

在向applyCh写入一条消息后,会调用CondInstallSnapshot()接口是用来判断是否可以实施快照的,比如判断一下快照的index是否小于节点的commitIndex。在实现CondInstallSnapshot接口时最好看一看config.go,了解它是如何被调用的。

3 结果

下图是2D的运行结果。2D其实写码不太难,关键是理解快照技术的含义,并且对前面代码做好修改。常见的坑就是log坐标的修改,因为某些日志已经被抛弃了,所以从前代码里直接访问rf.logs[index]的地方可能会有错,要转换为rf.logs[index - rf.lastSnapshot]。
在这里插入图片描述
最后展示一下所有测试通过的截图,希望大家做lab愉快:
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值