首页 > 其他分享 >MIT 6.5840 Raft Implementation(2B, Log Replication)

MIT 6.5840 Raft Implementation(2B, Log Replication)

时间:2023-07-24 14:22:36浏览次数:35  
标签:需要 Log Implementation 6.5840 领导人 指令 2B Raft 日志

Raft实现思路+细节(2B)

任务分解

2B中最主要的任务就是进行日志的复制。Raft是一个强领导人的系统,这意味着所有的日志添加都是由领导人发起的,与之相类似的,还有很多其他的结论(它们都是比较显然的),读者可以自行证明。

我们可以这样地分解复制日志的过程

  1. 我们首先需要完善Raft结构体的内容。

     

    我们对新加入的内容进行解释:

    • commitIndex:这代表了每一个Raft中最高的已经提交的日志下标,它表示对于这个下标以内的所有日志,我们都已经和领导达成共识。可以想象,它的更新是在收到RPC的时候完成的,因为如果领导人提交了某一条指令,且某个追随者有这条指令,那么就可以认为是达成共识的了,后续可以进行应用等操作。

    • lastApplied:这是一个紧跟commitIndex的成员,他指代的是每一个Raft中已经应用到状态机中的日志下标的最大值。我们会对每个Raft有一个轮询(至少我是这么实现的),如果lastApplied<commitIndex,那么就把这个区间内的所有指令应用到复制状态机上。

    • nextIndex(对于领导人):这代表的是对于每个成员,下一组要发的指令的下标的最小值,可以想象它代表着领导人和每个成员在哪些日志上达成了一致,它的更新应该是在AppenEntriesRPC中实现的。

    • matchIndex(对于领导人):这代表的是,对于每个成员,和领导人达成一致的下标的最大值(当然,你可以期待一般matchIndex=nextIndex-1)。我们通过它来决定要提交到哪一条指令(也即大部分人matchIndex的下界)。

  2. 经过上层服务器的多次尝试,我们终于在领导人这里加了一条日志:我们需要完成Start()函数,它的参数为一条指令(一个空的interface),返回的是这条指令在领导人这边的日志编号,领导人的任期,和这个人是否是领导人。同时,在Start函数中我们也要显式地向每一个追随者发一条心跳(其实就是AppendEntriesRpc).

  3. 类似于MakeElection函数,我们需要完成launchAppendEnries()这一函数,并处理回复信息。

  4. 我们需要完成AppendEntries()函数,在里面完成RPCHandler的功能。

  5. 我们需要完成上文中提到的轮询,对每一个Raft开一个Go程来检查要不要提交某一些指令,如果是的话,那就加到applyCh内(这个applyCh也需要自己完成)。

实现细节

  1. Start中,我们需要:

    • 增加log

    • 改变lastLogIndex, lastLogTerm

    • 开Go程来发送信息:go rf.launchAppendEntries(peerId)

  2. 我们首先需要发送AppendEntriesArgs,然后需要考虑AppendEntriesReply,具体来说:

    • 需要遵循Rules For All Servers,如果自己的任期变大,不需要处理;如果Reply的任期更高,变成追随者......(建议参考raft-extended)

    • 如果回复显示成功,那么把nextIndex, matchIndex都增加,并考察commitIndex是否也可以增加(看看是不是有一半的matchIndex)都超过了某一个值

    • 如果回复显示失败,我们就把nextIndex[peerId]减少一,来向下匹配。(在后文中我们会看到对于这一点的明显优化)

  3. 这是2B中的核心内容,我们在这里考察论文中的图示:

     

  4. 这个比较简单,只要知道“信道”是啥基本就可以了。

注意事项

  • 在上面这张图中,Reply false的意思是直接返回

  • 这里第三条的conflicts with的实现需要细细思考。如果接收者的日志中的每一条都是正确的,那么不需要截断(我到2C才发现这个)

  • 对于Rules For All Server而言,如果变成Follower,不需要返回。这一点上的处理是和2A一致的。

关于评测

 

 

标签:需要,Log,Implementation,6.5840,领导人,指令,2B,Raft,日志
From: https://www.cnblogs.com/lixingyang/p/17577077.html

相关文章

  • pdf 等所有文件通过blog强制下载函数 downloadFileFromBlobByToken
    downloadFileFromBlobByTokenpdf等所有文件通过blog强制下载函数downloadFileFromBlobByTokenimport{getToken}from'@/libs/util'exportconstdownloadFile=src=>{console.log(src)letiframe=document.createElement('iframe')iframe.sr......
  • Revit二次开发之 PolymeshTopology
    PolymeshTopology 表示多边形网格拓扑的类,用于描述多边形的的图形信息。多边形网格的拓扑结构由多个点和由这些点形成的三角形面组成。每个方面由点阵列的三个索引来确定。多边形网格可以指定UV坐标,并且始终至少关联一个法线。非平面多边形网格可能有一个以上的法线可用;多边形网......
  • Avalonia中用FluentAvalonia+DialogHost.Avalonia实现界面弹窗和对话框
    Avalonia中用FluentAvalonia+DialogHost.Avalonia实现界面弹窗和对话框本文是项目中关于弹窗界面设计的技术分享,通过FluentAvalonia+DialogHost.Avalonia开源nuget包来实现项目中需要弹框显示的界面和所有的对话框的展示。效果如下:1.项目介绍本项目是基于Avalonia的G......
  • java log level
    Java日志级别的实现简介Java日志级别是一个非常常用的功能,用于控制不同级别的日志输出。在开发过程中,合理设置日志级别可以帮助我们更好地定位和解决问题。本篇文章将介绍如何实现Java日志级别,并提供代码示例和注释说明,帮助刚入行的小白快速学习和掌握这一重要的开发技能。实现......
  • springboot启动依赖冲突(log4j2)
    报错示例:LoggerFactoryisnotaLogbackLoggerContextbutLogbackison1.解决方案:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId><......
  • mysql redo_log_buffer_size
    MySQLredo_log_buffer_size详解在MySQL中,redolog是一种用于保证数据持久性的机制。当我们进行数据修改时,MySQL会将这些修改操作记录到redolog中,以便在系统崩溃或重启后,可以使用redolog来恢复数据的一致性。redolog的大小对于系统的性能和可靠性都有着重要的影响,本文将详细介......
  • mysql /alidatal/data2/mysql/cong.log 存储位置
    MySQLbinlog详解及使用什么是MySQLbinlogMySQLbinlog(二进制日志)是MySQL数据库引擎提供的一种日志文件,记录了对数据库进行的修改操作,包括插入、更新和删除等操作。它的主要作用是用于数据恢复和数据复制。为什么需要使用MySQLbinlog数据恢复当数据库发生故障或者误操作导致......
  • python 怎么查看log值
    Python如何查看log值在开发和调试过程中,查看log值是一种常见的方法,可以帮助开发人员理解代码的执行过程、定位问题和优化性能。Python提供了多种方法来查看log值,本文将介绍其中几种常用的方法。1.使用print语句使用print语句是最简单直接的方法之一。通过在代码中......
  • verilog时序单元分频器
    分频电路2.2.1简单的计数器计数器实质是对输入的驱动时钟进行计数,所以计数器在某种意义上讲,等同于对时钟进行分频。例如一个最大计数长度为N=2^M(从0计数到N-1)的计数器,也就是寄存器位数为M,那么寄存器最高位的输出为N=2^M分频,次高位为N/2分频...例如下面的代码:moduletest#(......
  • go语言log相关
    log包Go标准库中有log包,提供了简单的日志功能。输出格式输出换行输出解释log.Print()log.Printf()log.Println()类似fmt.Print*log.Fatal()log.Fatalf()log.Fatalln()相当于log.Print*+os.Exit(1)log.Panic()log.Panicf()log.Panicln()相当于log.P......