6.824 Raft Lab2C
实验做什么?
持久化
- 这个很简单。只要参照persist()和readPersist()的注释,编写这2个函数。内容都很简短。然后凡是程序中有修改currentTerm、votedFor、log的地方,都在其后加一句persist(),就可以了。
- currentTerm持久化是为了term不会变小。
- votedFor持久化是为了防止重复投票。
- log持久化是为了防止已经commit的数据丢失。
- 持久化就是写入磁盘,国内的黑话好像叫做“落盘”。其实未必要写入磁盘,课程里面说也可以写到带电池的RAM里,
加速的log回溯
- 这个优化不做无法通过2C的部分测试。
- 我根据学生指南和课件拼凑出下面的实现。
- 能通过测试,但是我还是不太理解。
- 大概的想法是这样:
- follower的Term我们叫Term F (
reply.ConflictTerm
),leader的Term我们叫Term L。现在两者不一致。 - 要区分Leader有没有Term F
- 如果有,那么只能回溯到检查Leader的Term F最后一个log项的一致性。(至少跳过整个Term L,也可能跳过更多Term)
lastEntryWithTerm(reply.ConflictTerm)
是Leader记录的Term F的最后一项,next指向它 + 1,那么AppendEntries检查的就是这个最后一项的一致性。 - 如果没有,那么Follower可以跳过整个Term F,直接回溯到检查它之前的Term F2。
reply.ConflictIndex
是Term F的第一项,nextIndex指向它,那么AppendEntries检查的就是它之前的Term F2的一致性。
- 有的地方写first log entry,有的地方又提到last log entry,很容易混淆。其实无论如何,都是从一个Term的最后一个log项开始检查起。也就是说nextIndex指向下一个term的第一个log项。
参见
Raft第2课 NOTES
Student’s Guide