首页 > 其他分享 >Lab3 记录

Lab3 记录

时间:2024-09-24 23:33:57浏览次数:1  
标签:Term Candidate 记录 RPC Lab3 Follower 日志 Leader

Part 3A: leader election

1.选举主要流程

  1. 新服务器加入集群

服务器在启动时状态是Follower。只要持续接收到Leader或Candidate的心跳信息,就继续保持Follower状态。

  1. 开始选举

每个Server都有一个随机的选举超时时间,选举超时在一个固定区间内随机选择(例如,150-300毫秒)

如果Follower在选举超时时间内未收到有效的心跳信息,就认为当前没有有效Leader,转换自己为Candidate,发起选举。

心跳消息:一般是不包含日志条目的AppendEntries RPC

  1. 投票规则

服务器收到RequestVote RPC时,根据以下规则进行投票:

服务器以先到先得的方式投票,且每个任期只能投一票。

  • 如果收到的RPC的任期小于服务器当前的任期,拒绝投票
  • 如果服务器已经为当前任期投过票,或收到的RPC中的日志不如自己的日志新(最后一个条目的任期较旧或者任期相同但是编号较小),拒绝投票。
  • 如果以上情况都不满足,服务器会为Candidate投票,并重置自己的选举超时时间。
  1. 选举过程
  • 若选举过程中,Candidate收到其他Leader的心跳信息,且该Leader的任期大于等于候选人的任期,那么Candidate会承认新Leader并转回Follower状态;反之继续进行选举。
  1. 选举结果
  • 若Candidate获得的选票超过半数(3/5),则赢得选举,成为新Leader。同时向所有Server发送心跳消息,以防止新的选举。
  • 若选举超时,没有选出Leader,即没人获得多数票,一般是因为同时有多个Follower成为了Candidate。这种情况下,Candidate会等待一个随机的选举超时时间,增加任期,重新开始新一轮选举。

2.各组件逻辑

  1. 各组件都要遵守的规则

    任意RPC中包含的term大于自身term,则更新自己的term,并将自己转为follower状态,本节主要是心跳RPC和RequestVote RPC

  2. 随机超时检测ticker()

    功能:检测是否需要进行选举,使用Goroutine并行运行

    • role == Leader:跳过所有检测

    • role != Leader:

      若未收到心跳消息或未投票给任何人,举行选举

  3. 接收到心跳消息

    1. 如果心跳Term<当前Term,拒绝心跳,直接返回

      心跳TermTerm==当前Term心跳TermTerm>当前Term,则重置超时检测

    2. role==Candidaterole==Leader&&心跳Term>当前Term

      • 转回Follower

      • 更新当前Term为心跳Term

      • 更新LeaderID为心跳发送方

      • 更新VoteFor为心跳发送方

  4. 接收到投票请求

    说明已经有人开始选举,因此重置超时检测器,推迟自身可能要开始的选举

    1. 如果请求投票RPC Term<当前Term,拒绝

    2. 如果请求投票RPC Term>当前Term,投票

      更新自身Term

      如果当前Role!=Follower,转回Follower

    3. 如果请求投票RPC Term==当前Term,且当前Term没有投过票,投票

  5. 接收心跳超时,开始选举

    1. 配置自身角色

      1. Role切换为Candidate
      2. 投票给自己
      3. 当前Term+1
    2. 向其他Server请求投票

      票数过半,当选Leader

      1. 切换Role为Leader
      2. 更新LeaderID为自己
      3. 启动心跳发送程序

3.结果

测试6K次

image-20240901184324743

单次用时

image-20240924012301525

代码地址:https://github.com/INnoVationv2/6.5840/tree/Lab-3A-Dev/src/raft

go test -run 3A -count 1000 -failfast -timeout 3000m -race

Part 3B: log

  1. 完善结构体,将图2中State、AppendEntries RPC、RequestVote RPC的所有参数都写进代码

  2. 先从5.3节开始,实现不出错情况下Raft的处理逻辑,从Leader当选后开始

    当Leader收到客户端提交的命令时

    1. 根据客户端命令创建新的日志条目,日志条目由命令和任期编号组成。
    2. 向所有Follower并行发送AppendEntries RPC,其中包含待复制的旧条目、新条目、前一个日志条目的索引任期
    3. Follower收到AppendEntries RPC后,先检查其中的前一个日志条目的索引任期是否与自己的日志匹配。若匹配,则添加新条目并回复成功。若不匹配,则拒绝并回复失败。
    4. 当Leader收到包括Leader在内超过半数Follower的确认后,日志条目就被认为是safely replicated
    5. 之后,Leader执行条目到自己的状态机,然后将已执行的最大日志目录编号Index记录下来,下次与Follower通信时,会将其附上,这样Follower就知道Index之前的条目都已执行,然后Follower就也会执行这些条目到自己状态机。
    6. 将日志条目执行到状态机后,返回操作结果给客户端。
  3. 接下来实现日志修复逻辑

    Leader发生崩溃时,可能会导致日志不一致,旧Leader可能没有完全复制日志到其他服务器,Follower可能缺少leader的条目、也可能有Leader没有的条目。

    在Raft中,Leader会强制Follower复制自己的日志以保持一致。Follower日志中的冲突条目会被Leader日志覆盖。

    日志冲突处理步骤:

    image-20230425175616580
    1. Leader为每个Follower维护一个nextIndex,这是Leader下一次给Follower发生日志条目的起始编号
    2. Leader首次当选时,将所有nextIndex值初始化为日志中最后一个值之后的索引(图7中的11)。如果Follower与Leader的日志不一致,下一次AppendEntries RPC肯定会失败。失败后,Leader减少nextIndex并重试AppendEntries RPC。最终,nextIndex将达到和Follower日志匹配的点。
    3. 成功匹配后,AppendEntries将成功,Follower将删除日志中的所有冲突条目,并从Leader日志中追加条目。一旦AppendEntries成功,Follower与Leader的日志将一致,并且在该Term内始终保持一致。
  4. 继续实现论文中,为保证Raft正确性所做的一系列限制

    1. 选举限制

      防止未包含所有已提交条目的Candidate赢得选举

      收到投票请求时,投票人会将Candidate日志和自己的日志进行对比,

      • 如果Candidate的日志和投票人的至少一样新,投票
      • 如果投票人的日志比Candidate更新,不投票

      日志的定义:通过比较日志中最后一个条目的Index和Term来确定。

    2. 前一个Term的日志项

      对前一个Term的日志,不通过计算副本数规则提交,只对当前Term的日志项通过计算副本数提交,因为根据Log Matching属性,所有之前的条目都会被间接提交。

注:最近进行过日志发送或正在进行日志发送的话,本轮发送心跳暂停

一些坑

  1. 当发送非心跳消息到Follower超时时,若还是Leader,且term未变,需要持续重试

  2. Follower在接收到AppendEntries时,更新CommitIndex同样要遵循只提交当前任期日志项的原则

  3. Leader发送成功,更新NextIndex和MatchIndex时,先比较大小再更新,因为发的早的消息可能回复的比发的晚的消息更早

    如下两条消息

    {PrevLogIndex:5 PrevLogTerm:2 LeaderCommit:5 Len:4}
    {PrevLogIndex:5 PrevLogTerm:2 LeaderCommit:5 Len:5}
    

    第一条回来,NextIndex应该更新为10,第二条回来,NextIndex应该更新为11

    但是第二条如果回来的比第一条晚,NextIndex就会->11->10,从而出错

  4. 创建AppendEntries时,使用Copy,而不是切片引用,会出现DataRace

结果

3B测试100次

image-20240923161109298

单次用时

image-20240924012653056

Part 3C: persistence

这章就是在Persistent state发生改变时,及时持久化

如果测试报错,99%都是前两节没有写好

结果

3C测试100次

image-20240924012047002

单次用时

image-20240924012711612

Part 3D: log compaction

  1. Snapshot的定义:snapshot中保存的是已Commited日志的压缩,比如x+2 x-1,则Snapshot只需要存储x=1

  2. 当接收到Snapshot时,可以直接将其发送给tester,无需等待CommitIndex的确认,因为Leader的CommitIndex一定大于Snapshot

  3. Snapshot中保存的是已Commited日志,所以和Commit日志一样,只能向前推进,不能后退

    关于这一点有一种情况需要处理

    三个Server

    Leader最大Log Index为140,snapshop包含Index135之前的日志

    Follower1 和Leader同步

    Follower2 最大Log Index也是140,但是Snapshot只包含Index 120之前的日志

    之后Leader失效,Follower2当选Leader,发送snapshot给Follower1,Follower2已经有了更新的snapshot,所以没有更新

    Follower2将nextIndex[1]更新为121,下次发送日志prevLogIndex就是120,此时Follower会发现找不到Index 为120的日志

结果

测试100次

image-20240924231617401

单次用时

image-20240924232051965

标签:Term,Candidate,记录,RPC,Lab3,Follower,日志,Leader
From: https://www.cnblogs.com/INnoVationv2/p/18430335

相关文章

  • 2024.9.[23, 24]训练记录
    23上午whk。辅助角公式。诱导公式。23下午莫队:原序列分块。询问排序:第一关键字为左端点所在块的编号,第二关键字为右端点编号。回滚莫队:适用于增加或删除操作其中一个复杂度较大,但另一个较小的情况。可以做到只使用一种操作。排序后按照左端点的块编号一块一块做。排完......
  • redis内容记录
    redis的基本数据类型String:是最基本的数据类型,它可以存储任何二进制安全的数据。不仅能存放文本数据,还能保存图片、音频、视频、压缩文件等二进制数据。它们通常用于缓存。Hash:哈希类型,其中键值对中的值本身又是一个键值对结构,hash特别适合用于存储对象。List:Redis列表,一个......
  • 20240924 练习记录
    3个DP,还想了几道题,但不会。*P3349[ZJOI2016]小星星考虑树上的点最终会对应在图上的哪个点,设\(f_{x,i}\)表示树上的点\(x\)对应图上点\(i\)时的方案数,当\(x\)对应\(i\)后,在树上\(x\)的所有子节点也必须像在树上一样,在图上和\(i\)之间有连边,有了这条限制,可以写......
  • 化学套卷练习记录
    目录化学套卷练习记录202412024.9.202024苏州期初——【考试】59/7522024.9.242023年4月石家庄二模——【练习】58化学套卷练习记录202412024.9.202024苏州期初——【考试】59/75【总结】待upd【传送门】https://www.bilibili.com/video/BV15wsme5ELC22024.9.242023......
  • 微信聊天记录恢复最新恢复小技巧!
    微信在日常聊天记录中存有许多重要的数据,如工作文件、转账记录、视频照片等。这些聊天记录既便于日常工作的复盘,也能作为珍贵的聊天记忆保存在微信上。但是,如果我们不小心把微信删了,那聊天记录需要怎样恢复呢?针于对这个问题,在这里小编给大家总结了几点,帮助大家恢复微信聊天记录......
  • 打靶记录18——narak
    靶机:https://download.vulnhub.com/ha/narak.ova推荐使用VMWare打开靶机难度:中目标:取得root权限+2Flag攻击方法:主机发现端口扫描信息收集密码字典定制爆破密码Webdav漏洞PUT方法上传BF语言解码MOTD注入CVE-2021-3493提权主机发现arp-scan-l尝......
  • Drive.js 的一些 Api 使用记录
    文章目录2024年drive.js的基础使用想在下一步的时候处理些逻辑呢?(同步)Element的各种选择器2024年drive.js的基础使用安装就跳过了npminstalldriver.js,一行代码就可以搞定官网的BasicUsage基础使用的截图如下:想在下一步的时候处理些逻辑呢?(同步)......
  • nodejs child_process 操作git 提交记录 提取git commit信息
    /***记录发布时的commit信息,用于区分内网版本包之间的差异*/importpathfrom'path';import{writeFileSync}from'fs';import{execSync}from'child_process';letoutputFileName=process.argv[2];if(!outputFileName){outputFileNam......
  • JL-22 风速记录仪 记录 采集二合一 断电自动存储
    功能及特点本机体积小巧美观,大屏幕液晶显示,全中文操作菜单,操作简单,性能可靠,记录间隔可根据要求从1分至24小时任意设置。(但由于存储器空间有限,设置后也可查看存储信息,以确定在所设定的间隔时间下可以存储多长时间)全程跟踪记录风速数据,记录时间长,集数据采集、记录于一体,并具有......
  • 记录我的码农之路6
    2024.9.23    今天学习了html的常用标签,工具是webstorm<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>国家主权神圣而不可侵犯</title></head><fontsize="5"face="微软雅......