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操作实际上就是将一个输入文件拆分 ...
随机推荐
- XCTF练习题---WEB---simple_js
XCTF练习题---WEB---simple_js flag:Cyberpeace{786OsErtk12} 解题步骤: 1.观察题目,打开场景 2.打开该场景后发现是一个登录界面,随便输入一个密码, ...
- Mac IntelliJ IDEA插件开发,IDEA Plugin SDK路径
On Mac, select application icon in /Applications/ 官方文档: Setting Up a Development Environment
- InnoDB数据存储结构
MySQL服务器上 存储引擎 负责对表中数据的读取和写入工作,不同存储引擎中 存放的格式 一般是不同的,甚至有的存储引擎(Memory)不用磁盘来存储数据. 页 (Page) 是磁盘和内存之间交互的基 ...
- PXE实现无人值守批量安装服务器
今天我们使用PXE+Kickstart+TFTP+DHCP+FTP实现无人值守安装服务器. 一.无人值守所需服务介绍: 1)PXE PXE,远程引导技术 功能:使计算机通过网络启动 硬件要求:客户端的 ...
- How to fetch data with React Hooks
Where can I make API call with hooks in react? Async useEffect is pretty much unreadable How to fetc ...
- Spring Security之简单举例
核心功能 Spring Security提供了三个核心的功能: 认证(你是谁) 授权(你能干什么) 攻击防护(防止伪造身份) 一个简单例子 默认情况 在前面的开发中,都是将spring securit ...
- 使用Spring MVC开发RESTful API(续)
使用多线程提高REST服务性能 异步处理REST服务,提高服务器吞吐量 使用Runnable异步处理Rest服务 AsyncController.java @RestController @GetMa ...
- 爬取豆瓣喜剧类热门TOP60的电影
学习任务:爬取豆瓣喜剧类热门TOP60的电影并保存在douban.txt文件中. 代码示例: import requests url="https://movie.douban.com/j/ ...
- 【单片机】CH32V103C8T6 ——窗口看门狗
本章教程通过串口调试助手打印显示程序运行状态,具体现象如下: 若计数器值在上窗口值和下窗口值0X40之间的时候,进行喂狗操作,计数器重新计数,程序正常运行,串口打印显示:The program run ...
- 聚类--DBSCN
1.什么是DBSCN DBSCAN也是一个非常有用的聚类算法. 它的主要优点:它不需要用户先验地设置簇的个数,可以划分具有复杂形状的簇,还可以找出不属于任何簇的点. DBSCAN比凝聚聚类和k均值稍慢 ...