MIT 6.5840 Lab2C

编程入门 行业动态 更新时间:2024-10-27 00:30:53

<a href=https://www.elefans.com/category/jswz/34/1763515.html style=MIT 6.5840 Lab2C"/>

MIT 6.5840 Lab2C

文章目录

  • 前言
  • 1. 任务
  • 2. Lab2C - persist of Raft
    • 2.1 分析
    • 2.2 编码解码
  • 3. 测试
  • 4. 总结

前言

如果你的Lab2A和Lab2B完成的非常的好,那么Lab2C会非常轻松,因为只需要在所有需要持久化的部分进行调用即可。反之,找bug会非常痛苦。

1. 任务

如果基于 Raft 的服务器重启,它应该从原来的位置恢复服务。这就要求 Raft 保持持久的状态,以便在重启后继续运行。本文的图 2 提到了哪些状态应该是持久的。

真正的实现会在 Raft 的持久状态发生变化时将其写入磁盘,并在重启后重新启动时从磁盘读取状态。你的实现不会使用磁盘,而是通过 Persister 对象保存和恢复持久化状态(参见 persister.go)。无论谁调用 Raft.Make(),都要提供一个 Persister,它最初保存着 Raft 最近的持久化状态(如果有的话)。Raft 应从该 Persister 初始化其状态,并在每次状态改变时使用它来保存其持久化状态。请使用 Persister 的 ReadRaftState() 和 Save() 方法。

Raft官网
课程实验


2. Lab2C - persist of Raft

2.1 分析

这部分用于解决Raft Crash之后的恢复问题。我们要实现的接口是persist()readPersist(),分别对应着编码(encode)、解码(decode)。光从接口这块和之前比起来,就少了许多了,轻松不少。


以上三个变量就是Persister保存的持久化状态,所以当这三个变量变换的时候,我们就需要调用rf.persist()。也就是说,当我们宕机后,服务器重新启动就能快速恢复到这三个参数所在的地方。

  • currentTerm:第一个参数currentTerm好说,当你恢复后,你肯定还得知道你是哪个Term,而且每个Term只能投一票;
  • votedFor:这个参数应该是为了保证你宕机恢复后,确认你是否已经投过票了,所以也需要持久化;
  • log[]:肯定得保存啊,恢复状态就靠log的内容了,如果发现自己term比别人小,那么新的leader就会根据nextIndex给你发送全部的log。

2.2 编码解码

这部分官方都给我们写好了的,直接拿来用就好了。主要是投票和发送心跳日志的地方。

func (rf *Raft) persist() {w := new(bytes.Buffer)	// 创建缓冲区,实际上是一个字节切片e := labgob.NewEncoder(w)	// 创建一个新的labgob编码器,编码后的内容存放在w中e.Encode(rf.currentTerm)e.Encode(rf.votedFor)e.Encode(rf.log)raftstate := w.Bytes()	// 将缓冲区的内容赋值给raftstaterf.persister.Save(raftstate, nil)	// 在未实现快照之前,第二个参数设置为nil
}// restore previously persisted state.
func (rf *Raft) readPersist(data []byte) {if data == nil || len(data) < 1 { // bootstrap without any state?return}r := bytes.NewBuffer(data)d := labgob.NewDecoder(r)var(currentTerm intvotedFor intlog []logEntry)if d.Decode(&currentTerm) != nil ||d.Decode(&votedFor) != nil ||d.Decode(&log) != nil {fmt.Println("decode error!")} else {rf.currentTerm = currentTermrf.votedFor = votedForrf.log = log}
}

然后在我们之前写的代码有修改持久化参数的地方加入rf.persist()就可以了。

3. 测试

在提交之前,最好多次运行测试,并检查每次运行是否都打印出 PASS。

for i in {0..10}; do go test -run 2C -race; done

TestPersist12C,TestPersist22C和TestPersist32C:基础测试,断联peer后重连查看是否正常持久化数据
TestFigure82C:针对Figure.8的情况进行测试,每个操作都要求领导者(如果有)追加log。如果有一个领导者,那么该领导者很快就会失败,概率很高(可能不执行命令),或者过一段时间后崩溃,概率很低(很可能执行命令)。如果活动服务器的数量不足以构成大多数服务器,也许可以启动一个新服务器。新任期内的领导者可能会尝试复制尚未提交的日志条目。
TestUnreliableAgree2C:测试不稳定网络情况下能否达成一致,也就是RPC可能会有1-2秒的延迟或丢失
TestFigure8Unreliable2C:网络不稳定情况下测试Figure.8的情况
TestReliableChurn2C和TestUnreliableChurn2C:分别在稳定和不稳定情况下,每个peer有低概率崩溃重启,在此基础上,进行大量的log追加与提交。

之前一直通过不了TestUnreliableAgree2CTestFigure8Unreliable2C,我把HeartBeat时间改为了50~100ms,就可以了。跑了50次,都PASS了,可能1000遍会有问题吧,但我没测了。如果有网友测了,可以评论区说一下,感谢!

4. 总结

这一节感觉蛮简单的,算是提前完成了任务了。后面就剩下一个日志快照了,成功就在眼前。

今天看到一段小作文,感觉非常符合我今天的心境,分享一下给大家,希望大家也能“追风赶月莫停留,平芜尽处是春山”。

失之东隅,收之桑榆。人生海海,山山而川,不过尔尔。昨日之深渊,今日之潜谈。路虽远,行则将至,事虽难,做则可成。纵然,欲买桂花同载酒,终不似,少年游。亦要追风赶月莫停留,平芜尽处是春山。

回头看:轻舟已过万重山,
向前看:前路漫漫亦灿灿。

更多推荐

MIT 6.5840 Lab2C

本文发布于:2024-02-11 22:09:10,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1683839.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:MIT   Lab2C

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!