概述
[持续更新中…]
文章目录
- 前置
- 1. 链接
- 2. 环境问题
- 3. 建议
- lab-2A leader election (moderate)
- 1. 思路
- 1. 主要流程
- 2. 选举超时定时器实现思路
- 3. 心跳问题
- 4. 并发 RPC 请求
- 2. 遇到问题
- Lab-2B Log
- 1. 思路
- TestBasicAgree2B
- 2. 问题
- 报错: apply error: server 1 apply out of order 7
- 调用 RPC 的接口设置一下超时时间
- 心跳的判断问题
- Lab2C - persistence
- 思路
- 问题
前置
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. 遇到问题
- 存在 leader 无 failure 自动更换 term 问题
warning: term changed even though there were no failuresserver
收到 APPEND_ENTRY 时也要更新一下 选举超时的计时器
- 存在 fail 的服务器时选不出 leader 问题
票数计算问题 如果有 3 个服务 >=2 即可
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 的项。
原因:
- 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
}
Lab2C - persistence
思路
这一部分主要是将 论文 标注需要持久化的变量 在有变更时都同步到 Persister 中
相关状态变化的操作都封在函数中 改完状态后调一下 persist 方法即可
问题
通过上面的思路实现后 整个 2C 的实验基本没有问题,但是关于 Unreliable 的部分无法通过 (RPC 时延变高 且 fail 的次数变多)
对于 Unreliable 实验原本有 hint 需要我们优化 log back 的算法 实现日志主从之间快速同步
快速同步的算法可以看助教的 blog
An aside on optimizations
关键部分
2C 结果
最后
以上就是忧心手机为你收集整理的mit 6.824 RAFT 实验过程记录前置lab-2A leader election (moderate)Lab-2B LogLab2C - persistence的全部内容,希望文章能够帮你解决mit 6.824 RAFT 实验过程记录前置lab-2A leader election (moderate)Lab-2B LogLab2C - persistence所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复