MIT 6.824 Lab2C Raft之持久化
书接上文Raft Part B | MIT 6.824 Lab2B Log Replication。
实验准备
- 实验代码:
git://g.csail.mit.edu/6.824-golabs-2021/src/raft - 如何测试:
go test -run 2C -race - 相关论文:Raft Extended
- 实验指导:6.824 Lab 2: Raft (mit.edu)
实验目标
- 完成
persist()和readPersist()函数,编码方式参照注释。 - 优化
nextIndex[]回退方式,否则无法通过所有测试。
一些提示
- 测试涉及服务器故障和RPC失败等不确定事件,多次运行测试确保通过。
- 需要持久化的部分包括
currentTerm、votedFor、log。 - 有关
nextIndex[]回退优化可以查看Students' Guide to Raft。 - 在Lab2A和Lab2B中测试未能发现的错误可能会在Lab2C中暴露出来。
持久化
这部分其实很简单,代码中的注释已经很清晰了,当然你要注意data race问题。
func (rf *Raft) persist() {
w := new(bytes.Buffer)
e := labgob.NewEncoder(w)
e.Encode(rf.currentTerm)
e.Encode(rf.votedFor)
e.Encode(rf.log)
rf.persister.SaveRaftState(w.Bytes())
}
func (rf *Raft) readPersist(data []byte) {
if data == nil || len(data) < 1 {
return
}
r := bytes.NewBuffer(data)
d := labgob.NewDecoder(r)
d.Decode(&rf.currentTerm)
d.Decode(&rf.votedFor)
d.Decode(&rf.log)
}
nextIndex优化
Part B中对于失败的AppendEntries请求,让nextIndex自减,这样效率是比较慢的。
优化点1
如果follower.log不存在prevLog,让Leader下一次从follower.log的末尾开始同步日志。
优化点2
如果是因为prevLog.Term不匹配,记follower.prevLog.Term为conflictTerm。
- 如果
leader.log找不到Term为conflictTerm的日志,则下一次从follower.log中conflictTerm的第一个log的位置开始同步日志。 - 如果
leader.log找到了Term为conflictTerm的日志,则下一次从leader.log中conflictTerm的最后一个log的下一个位置开始同步日志。
nextIndex的正确位置可能依旧需要多次RPC才能找到,改进的流程只是加快了找到正确nextIndex的速度。
AppendEntries中有逻辑如下。
reply.Term = rf.currentTerm
reply.Success = false
if len(rf.log) <= args.PrevLogIndex {
reply.ConflictIndex = len(rf.log)
reply.ConflictTerm = -1
return
}
if rf.log[args.PrevLogIndex].Term != args.PrevLogTerm {
reply.ConflictTerm = rf.log[args.PrevLogIndex].Term
for i := 1; i <= args.PrevLogIndex; i++ {
if rf.log[i].Term == reply.ConflictTerm {
reply.ConflictIndex = i
return
}
}
}
Heartbeat中有逻辑如下。
if !reply.Success {
if reply.ConflictTerm == -1 {
rf.nextIndex[id] = reply.ConflictIndex
} else {
conflictIndex := -1
for i := args.PrevLogIndex; i > 0; i-- {
if rf.log[i].Term == reply.ConflictTerm {
conflictIndex = i
break
}
}
if conflictIndex != -1 {
rf.nextIndex[id] = conflictIndex + 1
} else {
rf.nextIndex[id] = reply.ConflictIndex
}
}
}
实验总结
Part C并不算是Raft算法的核心部分,关于nextIndex的优化本文是参照了Students' Guide中的方式。
如果你完成了持久化和回退优化两个部分依然无法通过所有测试,那可能要仔细的检查Part A和Part B是否遗漏了某些细节。
最后,为了证明我不是在乱写,附上我的测试结果。
MIT 6.824 Lab2C Raft之持久化的更多相关文章
- MIT 6.824 Lab2D Raft之日志压缩
书接上文Raft Part C | MIT 6.824 Lab2C Persistence. 实验准备 实验代码:git://g.csail.mit.edu/6.824-golabs-2021/src ...
- MIT 6.824 Llab2B Raft之日志复制
书接上文Raft Part A | MIT 6.824 Lab2A Leader Election. 实验准备 实验代码:git://g.csail.mit.edu/6.824-golabs-2021 ...
- MIT 6.824 Lab2A Raft之领导者选举
实验准备 实验代码:git://g.csail.mit.edu/6.824-golabs-2021/src/raft 如何测试:go test -run 2A -race 相关论文:Raft Exte ...
- MIT 6.824 lab1:mapreduce
这是 MIT 6.824 课程 lab1 的学习总结,记录我在学习过程中的收获和踩的坑. 我的实验环境是 windows 10,所以对lab的code 做了一些环境上的修改,如果你仅仅对code 感兴 ...
- MIT 6.824(Spring 2020) Lab1: MapReduce 文档翻译
首发于公众号:努力学习的阿新 前言 大家好,这里是阿新. MIT 6.824 是麻省理工大学开设的一门关于分布式系统的明星课程,共包含四个配套实验,实验的含金量很高,十分适合作为校招生的项目经历,在文 ...
- MIT 6.824学习笔记4 Lab1
现在我们准备做第一个作业Lab1啦 wjk大神也在做6.824,可以参考大神的笔记https://github.com/zzzyyyxxxmmm/MIT6824_Distribute_System P ...
- MIT 6.824 : Spring 2015 lab3 训练笔记
摘要: 源代码参见我的github:https://github.com/YaoZengzeng/MIT-6.824 Lab3: Paxos-based Key/Value Service Intro ...
- MIT 6.824 : Spring 2015 lab2 训练笔记
源代码参见我的github:https://github.com/YaoZengzeng/MIT-6.824 Lab 2:Primary/Backup Key/Value Service Overvi ...
- MIT 6.824 : Spring 2015 lab1 训练笔记
源代码参见我的github: https://github.com/YaoZengzeng/MIT-6.824 Part I: Word count MapReduce操作实际上就是将一个输入文件拆分 ...
随机推荐
- go学习第一课--语法基础
一.hello world 新建文件helloworld.go package main import "fmt" func main() { fmt.Println( ...
- 通过命令验证docker容器相当一个轻量级的Linux运行环境,且每个容器内都有一个属于自己的文件系统,容器之间相互隔离
一.docker的三个重要概念 1.镜像:打包项目带上环境,即镜像 Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序.库.资源.配置等文件外,还包含了一些为运行时准备的配置参数.镜像 ...
- wsgiref模块、web框架、django框架简介
"""web框架:将前端.数据库整合到一起的基于互联网传输的python代码 web框架也可以简单的理解为是软件开发架构里面的'服务端'""" ...
- 203. Remove Linked List Elements - LeetCode
Question 203. Remove Linked List Elements Solution 题目大意:从链表中删除给定的数 思路:遍历链表,如果该节点的值等于给的数就删除该节点,注意首节点 ...
- linux篇-Parse error: syntax error, unexpected ‘new’ (T_NEW) in /usr/local/nginx/html/cacti/lib/adodb
1首先这是基于lnmp模式进行的 2yum安装 yum -y install httpd mysql mysql-server php php-mysql php-json php-pdo 3lib库 ...
- BUUCTF刷题记录(更新中...)
极客大挑战 2019]EasySQL-1 直接通过输入万能密码:' or 1=1#实现注入: 思考:服务端sql语句应该为:select * from users where username='xx ...
- 记 iTextSharp 剪裁 PDF 指定区域的方法
原文 引用 itextsharp 5.5.13.2 itextsharp.xtra 5.5.13.2 方法 /// <summary> /// 截取pdf文件,例如把A4截出指定的A6区域 ...
- python之loggin模块与第三方模块
目录 logging模块详解 第三方模块 openpyxl模块 logging模块详解 主要组成部分 logger对象,用于产生日志 # 第一步,创建logger对象 logger = logging ...
- MMDeploy安装笔记
MMDeploy的TensorRT教程 Step1: 创建虚拟环境并且安装MMDetection conda create -n openmmlab python=3.7 -y conda activ ...
- IIS7 网站发布常见报错问题解决方案汇总
本文实例为大家分享了IIS7 网站发布常见问题,以及五种问题的解决方法,供大家参考,具体内容如下: 1.不是有效的Win32位应用程序 : 解决方案: 1).进入应用程序池=>选中网站=> ...