MIT 6.824: Distributed Systems- 实现Raft Lab2A

MIT 6.824: Distributed Systems是麻省理工大学的研究生公开课,主讲分布式系统。

该课程一共包含Lab1-4共4个大作业,Lab1是实现Mapreduce原型,Lab2-4是实现Raft以及基于Raft实现分布式KV存储。

我正在实现Lab2,也就是Raft核心算法,它被划分成了Lab2A、Lab2B、Lab2C三个子任务:

  • Lab2A:实现leader election、heartbeat。
  • Lab2B:实现Log replication。
  • Lab2C:实现state persistent。

这个拆解符合Raft算法的描述,也就是选主、日志同步、状态存储,是可以分开实现的,最终凑出一个完整的Raft实现。

学习资料

以MIT课程教案与视频为主:

中英文对照学习Raft论文:

实现Raft的时候基本就盯着Figure2的图片即可:

Lab2A实现

因为课程分为Lab2A、Lab2B、Lab2C,为了能留住每个子任务的代码状态,我决定把每个子Lab的代码实现贴到博客上,方便拆分回看,我不会讲解代码细节。

下面是我的Lab2A实现,已经通过了课程的单元测试:

结构体定义

Make 程序入口

GetState(单元测试会调用)

RequestVote相关

AppendEnties(仅心跳)

总结Lab2A

  • 一把大锁保护好状态,RPC期间释放锁,RPC结束后注意状态二次判定
  • request/response都要先判断term > currentTerm,转换follower
  • 一个currentTerm只能voteFor其他节点1次
  • 注意candidates请求vote的时间随机性
  • 注意requestVote得到大多数投票后立即结束等待剩余RPC
  • 注意成为leader后尽快appendEntries心跳,否则其他节点又会成为candidates
  • 注意几个刷新选举超时时间的逻辑点

其他了解:

  • 虽然Lab2A不要求关注persist状态的落地(currentTerm,voteFor,[]log),但是我稍微扫了一眼代码,发现它的persist其实还是写在内存里,供单元测试去check结果,因此猜测这门课可能不会真的实现raft如何持久化log这个存储部分(从目前来看的确是这样的)。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~