书接上文Raft Part B | MIT 6.824 Lab2B Log Replication

实验准备

  1. 实验代码:git://g.csail.mit.edu/6.824-golabs-2021/src/raft
  2. 如何测试:go test -run 2C -race
  3. 相关论文:Raft Extended
  4. 实验指导:6.824 Lab 2: Raft (mit.edu)

实验目标

  1. 完成persist()readPersist()函数,编码方式参照注释。
  2. 优化nextIndex[]回退方式,否则无法通过所有测试。

一些提示

  1. 测试涉及服务器故障和RPC失败等不确定事件,多次运行测试确保通过。
  2. 需要持久化的部分包括currentTermvotedForlog
  3. 有关nextIndex[]回退优化可以查看Students' Guide to Raft
  4. 在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.TermconflictTerm

  1. 如果leader.log找不到Term为conflictTerm的日志,则下一次从follower.logconflictTerm的第一个log的位置开始同步日志。
  2. 如果leader.log找到了Term为conflictTerm的日志,则下一次从leader.logconflictTerm的最后一个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之持久化的更多相关文章

  1. MIT 6.824 Lab2D Raft之日志压缩

    书接上文Raft Part C | MIT 6.824 Lab2C Persistence. 实验准备 实验代码:git://g.csail.mit.edu/6.824-golabs-2021/src ...

  2. MIT 6.824 Llab2B Raft之日志复制

    书接上文Raft Part A | MIT 6.824 Lab2A Leader Election. 实验准备 实验代码:git://g.csail.mit.edu/6.824-golabs-2021 ...

  3. MIT 6.824 Lab2A Raft之领导者选举

    实验准备 实验代码:git://g.csail.mit.edu/6.824-golabs-2021/src/raft 如何测试:go test -run 2A -race 相关论文:Raft Exte ...

  4. MIT 6.824 lab1:mapreduce

    这是 MIT 6.824 课程 lab1 的学习总结,记录我在学习过程中的收获和踩的坑. 我的实验环境是 windows 10,所以对lab的code 做了一些环境上的修改,如果你仅仅对code 感兴 ...

  5. MIT 6.824(Spring 2020) Lab1: MapReduce 文档翻译

    首发于公众号:努力学习的阿新 前言 大家好,这里是阿新. MIT 6.824 是麻省理工大学开设的一门关于分布式系统的明星课程,共包含四个配套实验,实验的含金量很高,十分适合作为校招生的项目经历,在文 ...

  6. MIT 6.824学习笔记4 Lab1

    现在我们准备做第一个作业Lab1啦 wjk大神也在做6.824,可以参考大神的笔记https://github.com/zzzyyyxxxmmm/MIT6824_Distribute_System P ...

  7. MIT 6.824 : Spring 2015 lab3 训练笔记

    摘要: 源代码参见我的github:https://github.com/YaoZengzeng/MIT-6.824 Lab3: Paxos-based Key/Value Service Intro ...

  8. MIT 6.824 : Spring 2015 lab2 训练笔记

    源代码参见我的github:https://github.com/YaoZengzeng/MIT-6.824 Lab 2:Primary/Backup Key/Value Service Overvi ...

  9. MIT 6.824 : Spring 2015 lab1 训练笔记

    源代码参见我的github: https://github.com/YaoZengzeng/MIT-6.824 Part I: Word count MapReduce操作实际上就是将一个输入文件拆分 ...

随机推荐

  1. XCTF练习题---WEB---simple_js

    XCTF练习题---WEB---simple_js flag:Cyberpeace{786OsErtk12} 解题步骤: 1.观察题目,打开场景 2.打开该场景后发现是一个登录界面,随便输入一个密码, ...

  2. Mac IntelliJ IDEA插件开发,IDEA Plugin SDK路径

    On Mac, select application icon in /Applications/ 官方文档: Setting Up a Development Environment

  3. InnoDB数据存储结构

    MySQL服务器上 存储引擎 负责对表中数据的读取和写入工作,不同存储引擎中 存放的格式 一般是不同的,甚至有的存储引擎(Memory)不用磁盘来存储数据. 页 (Page) 是磁盘和内存之间交互的基 ...

  4. PXE实现无人值守批量安装服务器

    今天我们使用PXE+Kickstart+TFTP+DHCP+FTP实现无人值守安装服务器. 一.无人值守所需服务介绍: 1)PXE PXE,远程引导技术 功能:使计算机通过网络启动 硬件要求:客户端的 ...

  5. 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 ...

  6. Spring Security之简单举例

    核心功能 Spring Security提供了三个核心的功能: 认证(你是谁) 授权(你能干什么) 攻击防护(防止伪造身份) 一个简单例子 默认情况 在前面的开发中,都是将spring securit ...

  7. 使用Spring MVC开发RESTful API(续)

    使用多线程提高REST服务性能 异步处理REST服务,提高服务器吞吐量 使用Runnable异步处理Rest服务 AsyncController.java @RestController @GetMa ...

  8. 爬取豆瓣喜剧类热门TOP60的电影

    学习任务:爬取豆瓣喜剧类热门TOP60的电影并保存在douban.txt文件中. 代码示例: import requests url="https://movie.douban.com/j/ ...

  9. 【单片机】CH32V103C8T6 ——窗口看门狗

    本章教程通过串口调试助手打印显示程序运行状态,具体现象如下: 若计数器值在上窗口值和下窗口值0X40之间的时候,进行喂狗操作,计数器重新计数,程序正常运行,串口打印显示:The program run ...

  10. 聚类--DBSCN

    1.什么是DBSCN DBSCAN也是一个非常有用的聚类算法. 它的主要优点:它不需要用户先验地设置簇的个数,可以划分具有复杂形状的簇,还可以找出不属于任何簇的点. DBSCAN比凝聚聚类和k均值稍慢 ...