MIT6.5840-2023-Lab2C: Raft-Persistence

2023-12-14 05:36

本文主要是介绍MIT6.5840-2023-Lab2C: Raft-Persistence,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前置知识

见上一篇 Lab2A。

实验内容

实现 RAFT,分为四个 part:leader election、log、persistence、log compaction。

实验环境

OS:WSL-Ubuntu-18.04
golang:go1.17.6 linux/amd64

Part 2C: persistence

大部分的bug都与这张图有关。如果前两次lab通过了千次以上测试,这边应该问题不大。注意rpc前后的状态判断。
在这里插入图片描述

实现持久化,重启后能快速恢复。真正的实现将在每次更改时在磁盘写下 raft 的持久状态,并在重新启动后从磁盘中读取状态。lab 实现时在 Persister 中存储和恢复。currentTerm、votedFor、log[]
persist 和 readPersist:通过 labgob实现。

// save Raft's persistent state to stable storage,
// where it can later be retrieved after a crash and restart.
// see paper's Figure 2 for a description of what should be persistent.
// before you've implemented snapshots, you should pass nil as the
// second argument to persister.Save().
// after you've implemented snapshots, pass the current snapshot
// (or nil if there's not yet a snapshot).
func (rf *Raft) persist() {// Your code here (2C).// Example:w := new(bytes.Buffer)e := labgob.NewEncoder(w)e.Encode(rf.currentTerm)e.Encode(rf.votedFor)e.Encode(rf.log)raftstate := w.Bytes()rf.persister.Save(raftstate, nil)
}// restore previously persisted state.
func (rf *Raft) readPersist(data []byte) {if data == nil || len(data) < 1 { // bootstrap without any state?return}// Your code here (2C).// Example:r := bytes.NewBuffer(data)d := labgob.NewDecoder(r)var currentTerm, votedFor intvar logs []Entryif d.Decode(&currentTerm) != nil ||d.Decode(&votedFor) != nil ||d.Decode(&logs) != nil {log.Println("decode fail")} else {rf.currentTerm = currentTermrf.votedFor = votedForrf.log = logslog.Println("restore success")}
}

优化:避免 leader 每次只往前移动一位;若日志很长的话在一段时间内无法达到冲突位置。若 leader 发送心跳时接收到的回复是 false,leader 会减小发送的 AppendEntriesArgs 中的 rf.nextIndex,但是这种每次仅减小 1 的方案无法在有限的时间内确定跟其他服务器发生冲突的下标位置。

func (rf *Raft) AppendEntries(args *AppendEntriesArgs, reply *AppendEntriesReply) {// Your code here (2A, 2B).rf.mu.Lock()defer rf.mu.Unlock()if args.Term > rf.currentTerm { // all serverrf.state = Followerrf.currentTerm = args.Termrf.votedFor = -1rf.persist()}if args.Term < rf.currentTerm {reply.Success = falsereply.Term = rf.currentTerm} else if len(rf.log)-1 < args.PrevLogIndex ||rf.log[args.PrevLogIndex].Term != args.PrevLogTerm {log.Println(rf.me, "mismatch", "len(rf.log)", len(rf.log), "args.PrevLogIndex", args.PrevLogIndex)reply.Success = falsereply.Term = rf.currentTermtimeout := time.Duration(250+rand.Intn(300)) * time.Millisecondrf.expiryTime = time.Now().Add(timeout)if args.PrevLogIndex > len(rf.log)-1 {reply.ConflictIndex = len(rf.log)reply.ConflictTerm = -1} else {reply.ConflictTerm = rf.log[args.PrevLogIndex].Termreply.ConflictIndex = 1for i := args.PrevLogIndex - 1; i >= 0; i-- {if rf.log[i].Term != reply.ConflictTerm {reply.ConflictIndex += ibreak}}}} else {reply.Success = truereply.Term = rf.currentTermtimeout := time.Duration(250+rand.Intn(300)) * time.Millisecondrf.expiryTime = time.Now().Add(timeout)// // delete// rf.log = rf.log[:args.PrevLogIndex+1]// // append// rf.log = append(rf.log, args.Entries...)insertIndex := args.PrevLogIndex + 1argsLogIndex := 0for {if insertIndex >= len(rf.log) ||argsLogIndex >= len(args.Entries) ||rf.log[insertIndex].Term != args.Entries[argsLogIndex].Term {break}insertIndex++argsLogIndex++}// for _, e := range rf.log {// 	log.Print(e)// }// for _, e := range args.Entries {// 	log.Print(e)// }if argsLogIndex < len(args.Entries) {rf.log = append(rf.log[:insertIndex], args.Entries[argsLogIndex:]...)rf.persist()}if args.LeaderCommit > rf.commitIndex {rf.commitIndex = int(math.Min(float64(args.LeaderCommit), float64(len(rf.log)-1)))log.Println(rf.me, "follower update commitIndex", "args.LeaderCommit", args.LeaderCommit, "len(rf.log)", len(rf.log), "rf.commitIndex", rf.commitIndex)}}}
// 修改前
// if args.PrevLogIndex > 0 {
// 	rf.nextIndex[i] = args.PrevLogIndex
// }
// 修改后if reply.ConflictTerm >= 0 {lastIndex := -1for i := len(rf.log) - 1; i >= 0; i-- {if rf.log[i].Term == reply.ConflictTerm {lastIndex = ibreak}}if lastIndex >= 0 {rf.nextIndex[i] = lastIndex + 1} else {rf.nextIndex[i] = reply.ConflictIndex}} else {rf.nextIndex[i] = reply.ConflictIndex}

实验结果

在这里插入图片描述
需要更多次实验,由于电脑性能原因无法开更多个线程跑,10次测试是通过的。

这篇关于MIT6.5840-2023-Lab2C: Raft-Persistence的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/491304

相关文章

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多

2023 CCPC(秦皇岛)现场(第二届环球杯.第 2 阶段:秦皇岛)部分题解

所有题目链接:Dashboard - The 2023 CCPC (Qinhuangdao) Onsite (The 2nd Universal Cup. Stage 9: Qinhuangdao) - Codeforces 中文题面: contest-37054-zh.pdf (codeforces.com) G. Path 链接: Problem - G - Codeforces

HNU-2023电路与电子学-实验1

写在前面: 这是电路与电子学课程的第一次实验,按照指导书的需求在Multisim软件搭建一个电路传感器模型,难度较小,细心完成就没有问题。 小tips:22级实验是采用上传到测试平台来进行功能检测,如果不通过则会打回修改后再重新提交,(我们那时候的评测系统特别特别慢,一次只能测一个同学,剩下同学就排队等着,久的时候甚至超过10个小时),这里列举一个常见的错误:热噪声有+号这端需要连接有源滤波器

【python】—— Python爬虫实战:爬取珠海市2011-2023年天气数据并保存为CSV文件

目录 目标 准备工作 爬取数据的开始时间和结束时间 爬取数据并解析 将数据转换为DataFrame并保存为CSV文件         本文将介绍如何使用Python编写一个简单的爬虫程序,以爬取珠海市2011年至2023年的天气数据,并将这些数据保存为CSV文件。我们将涉及到以下知识点: 使用requests库发送HTTP请求使用lxml库解析HTML文档使用dateti

Acrobat Pro DC 2023 for Mac/Win:全能型PDF编辑器深度解析

Adobe Acrobat Pro DC 2023作为一款跨平台的PDF编辑器,无论是对于Mac还是Windows用户,都提供了极为全面且强大的PDF处理功能。该软件凭借其卓越的性能和丰富的特性,成为了全球范围内用户处理PDF文档的首选工具。 一、强大的编辑功能 Acrobat Pro DC 2023内置了多种编辑工具,如文本编辑器、图片替换、页面调整等,使用户能够轻松地对PDF文档进行修改和

【行业报告】2023年消除类手游全球市场洞察

​更多消除内容: 长线消除游戏商业化设计案例:《梦幻花园》 - 游戏干饭之家 谈谈《开心消消乐》是如何做游戏商业化活动 - 游戏干饭之家 消除游戏展现了从简单的游戏玩法到复杂的社交互动,再到精细化运营的发展历程,其通过不断的创新和适应现代游戏的市场变化,依然活跃在市场的前沿 一、消除游戏分类定义 二、消除手游市场现状分析 消除手游近两年下载量增速表现优于整体手游表现,下

【数据分享】2000—2023年我国省市县三级逐月归一化植被指数(NDVI)数据(Shp/Excel格式)

之前我们分享过2000—2023年逐月归一化植被指数(NDVI)栅格数据(可查看之前的文章获悉详情),该数据来源于NASA定期发布的MOD13A3数据集!很多小伙伴拿到数据后反馈栅格数据不太方便使用,问我们能不能把数据处理为更方便使用的Shp和Excel格式的数据! 我们特地对数值在-0.2—1之间的NDVI栅格数据进行了处理,将2000-2023年逐月的归一化植被指数栅格分别按照我国省级行政边

Update Azure OpenAI npm Package to 2023-12-01-preview Version

题意:将 Azure OpenAI npm 包更新到 2023-12-01-preview 版本 问题背景: I am currently using the azure-openai npm package in my project with version 2023-03-15-preview. As per the latest updates, version 2023-12

[SWPUCTF 2023 秋季新生赛]Pingpingping

这种是ctf中比较简单的一类题,主要解法基本上也就那些形式。 这道题我给它提出来主要是涉及了一下比较零散的知识点,觉得想要跟大家分享一下。 <?phphighlight_file(__FILE__);error_reporting(0);$_ping = $_GET['Ping_ip.exe'];if(isset($_ping)){system("ping -c 3 ".$_ping)