6.824-lab2
; 1298 words
目录
快速开始
2A
2A主要实现领导选举和心跳检测功能,当领导出问题后,需要选举出新领导. 我们可以从测试逻辑入手分析,启动三个server,这里启动时会调用make逻辑,在make里通过ticker定期发起心跳检测【AppendEntries】。如果某个server没有收到心跳,则认为该server挂了,需要重新选举出新领导【RequestVote】。
- 初始状态:全部是follower
- 当follower一定时间未收到来自leader的心跳检测,认定目前没有有效leader,将自身状态转换为candidate,发起选举。这里不同节点的超时时间不同,避免多个节点同时发起选举而造成平票选举失败。
- 一旦节点获得多数票赢得选举,变成leader,开始发送心跳检测。
并发场景需要加锁,测试时使用-race可以检测数据竞争,修改后保证数据可用性。
2B
2b是关于日志Entry的同步,本质上是实现日志的同步与一致性校验。这里主要是实现Start接口,该接口负责接收client的command,leader节点将command写入本地日志后,同步到其他节点,确保各节点同步完成后,各节点将该日志同步到state machine。关于2B的测试逻辑也是测试关于写入command的一致性。
在2B中,基本逻辑未改变,主要涉及到日志同步,因此这里需要额外维护相关信息。
- nextIndex[]: nextIndex[i]表示leader希望节点i的下一个日志索引,由leader维护,当日志同步成功时更新,值为prevLogIndex+logEntries(此次同步日志)+1;当日志同步冲突时,值为冲突索引。
- matchIndex[]: matchIndex[i]表示leader和节点i已同步的最大日志索引,由leader维护。由于leader使用AppendEntries同步日志,所以在发送AppendEntries请求成功后维护。
- commitIndex: 维护集群已同步的最大日志索引,通过判断各节点的最大同步日志索引,即matchIndex[i]实现。同样在发送AppendEntries请求成功后由Leader维护。
- prevLogIndex/prevLogTerm: leader希望follower追加日志的索引的前一个位置(nextIndex[i]-1)以及任期,leader会将其作为AppendEntries的入参,把相关索引的日志同步给follower,follower收到AppendEntries请求后,会校验prevLogIndex和prevLogTerm,如果日志不存在或者日志项的term与prevLogTerm不一致,则返回错误。在论文中,当leader接收到错误返回时,会选择回退prevLogIndex,并重新发送AppendEntries请求,直到匹配成功,这样效率太低,因此可以优化为直接返回冲突索引。TestBackup2B就是对该功能的测试。
sequenceDiagram
participant Client
participant Leader
participant Follower
participant Candidate
Client->>Leader: 发送日志请求 (e.g., set x=5)
Leader->>Leader: 追加日志到本地 (log[index]=entry)
Leader->>Follower: 定期心跳
同步日志 Follower-->>Leader: 响应成功 Note over Leader,Follower: 正常情况下,Leader 会定期发送心跳/日志 Follower-->Candidate: 心跳超时
转为 Candidate Candidate->>Follower: RequestVote Follower-->>Candidate: 校验日志,同意选举 Candidate->>Leader: 半数同意,状态转为 Leader
同步日志 Follower-->>Leader: 响应成功 Note over Leader,Follower: 正常情况下,Leader 会定期发送心跳/日志 Follower-->Candidate: 心跳超时
转为 Candidate Candidate->>Follower: RequestVote Follower-->>Candidate: 校验日志,同意选举 Candidate->>Leader: 半数同意,状态转为 Leader
2C
This is a page about »6.824_lab2«.