MIT 6.824 lab3 KVRaft

lab3比lab2更加自由一点,主要是没有论文参照以及太多的资料可以查,而且调试难度也比较大。lab3A主要是实现基于Raft的kv server,client给server发送请求,然后server通过底层Raft来保持log的一致性,操作存储在内存中。lab3B主要是实现给内存快照,然后持久化到persister中。

我的代码:MIT6.824

lab3A

client

首先是实现client的操作,我们可以先通过查看test_test.go来了解测试过程,首先测试会新建几个serverclient,然后调用调用client的请求操作,client的请求操作会通过RPC调用server端的实现。

主要是实现client端的GetPutAppend方法,这个其实很简单,我们只需要在两个方法中,无限循环的尝试给server端发送RPC请求,如果成功就返回,不成功就继续发送。

为了防止在网络不稳定等情况下,server已经执行了操作,但是reply会没有回到client端,我们需要维护操作的幂等性,也就是判重。一个简单的方法是给每次client端发送的请求都加上一个ClientIdSeq,其中前者是每个client都有的唯一的64位编号,后者是随着每个新的请求递增的请求序列号。

由于我们测试的情况下,一个client如果某个请求还没有成功执行,那么它就会一直重复当前这个请求,所以我们只需要在server端记录一下对于每个client,已经收到的最大的序列号是多少即可。

server

server端主要是需要接收client发来的请求,然后执行,执行过程主要是把log发送到底层的Raft服务中,然后通过Raftcommit这个请求,然后在server端从channel中获取请求,然后应用到内存中,然后通知client端操作已经完成或者没有去完成。

整个过程是同步的,开始执行请求之后就必须等请求执行完成才能回复给client,所以可以通过RaftStart函数返回请求在log中的index,对于每个index创建一个channel来接收执行完成的消息,接收到了之后,知道是完成操作了,然后回复给client

需要单独开一个goroutine来监视apply channel,一旦底层的Raft commit一个,就立马执行一个。

lab3B

snapshot

snapshot其实并不复杂,需要做的几个点就是:

  • 启动server的时候,需要读取snapshot,并且要在底层的Raft开始运行之前。
  • Raft state也就是log以及其他两个参数超过一定限度的时候,server要将此时的内存状态保存为snapshot
  • 底层的Raft Leader在发送心跳的时候发现和Followerlog不匹配的点,在它现有的log中不存在(已经被存入snapshot),Leader就需要把AppendEntries RPC变为InstallSnapshot RPC,同时附带心跳效果。
  • InstallSnapshot RPC主要是截断log,然后其他判断和其他RPC相同,然后往apply channel里发送一个带snapshot的消息,当server端取出执行的时候,就是执行加载这个snapshot的操作了,而不是client的请求。
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值