mit 6.824 RAFT 实验过程记录

[持续更新中…]

前置

1. 链接

实验地址
公开课链接

2. 环境问题

lab 中介绍 实验代码只能运行在 linux, Mac 环境下
windows 下可以用 wsl 能成功 run 起来代码

3. 建议

a. 打日志时最好将毫秒时间戳输出 时间信息很重要
b. 单个 test 最好多 run 几次,不然会凑巧通过 实验原Hint提示如下:

events are non-deterministic, and you may get lucky and pass the tests, 
even though your code has bugs.
Typically running the test several times will expose those bugs.

c. 如果某个测试一直不通过可以看看测试代码的逻辑
d. 课程助教的 blog 可以仔细看一遍 遇到的很多问题都能从中找到答案
在做 2C 的时候就遇到 node 频繁成为 leader 的情况,最后在 blog 里找的解决方案

lab-2A leader election (moderate)

1. 思路

1. 主要流程

2A 的主要任务就是参照 raft 论文中 Figure2 ,将图中涉及的各个变量 rpc 接口定义好
在这里插入图片描述

2. 选举超时定时器实现思路

新增一个 goroutine 每隔 rand(150~300) -> T[ms], check 在上个 Tms内是否有来自其他 node 的 RPC 请求, 如果有继续循环 没有的话开始 election 流程。
判断的是否可以设置一个变量 gotRpc 如果有请求则将 gotRpc 设置为 true,
定时器每次 sleep 后 check 是否 gotRpc 如果是 将 gotRpc设置为 false 继续循环 否则开始选举

3. 心跳问题

新建一个 goroutine 每隔 H ms,向各个客户端发送 AppendEntries 请求

4. 并发 RPC 请求

每次向一个新的 node 发起 rpc 请求时,都新建一个 goroutine,使用 go channel
确保所有的 rpc 请求都执行完毕

2. 遇到问题

  1. 存在 leader 无 failure 自动更换 term 问题

warning: term changed even though there were no failuresserver

收到 APPEND_ENTRY 时也要更新一下 选举超时的计时器

  1. 存在 fail 的服务器时选不出 leader 问题
    票数计算问题 如果有 3 个服务 >=2 即可

lab2A
3. leader disconnect 后无新的leader 问题

发起投票时 阻塞至获取超过半数票即可
不要等所有节点都返回投票,不然如果有结点挂掉,永远不会选出新的leader

Lab-2B Log

1. 思路

TestBasicAgree2B

当前 test 会测试各个节点的日志在正常情况下是否一致
需要完成

  • 各个节点之间互相同步 log
  • 节点 commit 新的 log 后,需要将消息发送到 applyCh 中 (这一步很重要 测试代码通过这个 channel 获取节点的日志 如果没做这个 测试会一直不过)
    代码提示

2. 问题

报错: apply error: server 1 apply out of order 7

这个问题是在提交新的 cmd 时,测试代码发现之前的 index 有为 nill 的项。

原因:

  1. leader 没有提交自己的 commit 就 down 了,新的 follower 成为 leader后,持有未提交的 cmd,当新的 cmd 到达后直接提交的新的 cmd,导致漏掉了旧 term 的 cmd。 需要在 appendEntries 时对齐持有的 log

调用 RPC 的接口设置一下超时时间

不然会有无限阻塞的请情况

心跳的判断问题

可以初始化 Raft 的时候构建一个 channel, 之后在循环中用 select 如下
这样每次进入 valid rpc 请求都会重新开始计数

sleep := 150 + rand.Intn(150)
	select {
	case <- time.After(time.Duration(sleep) * time.Millisecond):
		needVote = true
	case <- rf.rpcGet:
		needVote = false
	}

RAFT 2B

Lab2C - persistence

思路

这一部分主要是将 论文 标注需要持久化的变量 在有变更时都同步到 Persister 中
相关状态变化的操作都封在函数中 改完状态后调一下 persist 方法即可

问题

通过上面的思路实现后 整个 2C 的实验基本没有问题,但是关于 Unreliable 的部分无法通过 (RPC 时延变高 且 fail 的次数变多)

对于 Unreliable 实验原本有 hint 需要我们优化 log back 的算法 实现日志主从之间快速同步


快速同步的算法可以看助教的 blog

An aside on optimizations

关键部分
加速日志同步
2C 结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值