6.824 Spring 2020 -- Lab 2A

实验说明:https://pdos.csail.mit.edu/6.824/labs/lab-raft.html

可视化:http://thesecretlivesofdata.com/raft/

 

实现目标

根据论文Figure 2和5.2实现Raft系统的选主和心跳

 

编程环境

1.  最终我们希望的目标是可以对raft目录下test文件进行测试,2A实现主要进行的测试代码有前2个,执行"go test -run 2A"

2. 在进行编程和调试时,我主要使用了goland编辑器,需要先设置下gopath,如下

 

3. 设置完成后,如果你直接执行下面的函数的话,会报错,是因为项目使用的import方式的问题

 

这个问题的原因在于在raft/raft.go、raft/config.go和raft/labrpc.go的代码里面有一个Import,是直接import了"../labrpc"和"../labgob",我们将GOPATH修改之后,需要把它们改成"import labrpc"和"import labgob"

当然也可以在不修改GOPATH的情况下进行修复这个问题,可以放置 

 6.824到原本src/github或者哪个项目里面,如下

 

 完成上述步骤之后就可以直接运行test代码了

整体流程

 1. 整个选主的流程其实就是一个raft server不断监控自身状态做出选择的过程,整个过程大致如下:

  • 初始化一个raft server,配置对raft的参数(参考论文figure 2里面的State表格),相较与论文,我们这里还需要多一个state,表示raft server的身份;还有一个expireTime,用于表示过期时间(follower和candidate的进行投票请求的时间,也是leader进行发送心跳请求的时间),这个过期时间需要我们不断进行动态更新
  • 如果自身状态是Follower的话,发生过期时间已经到达,就转换为Candidate,然后发送投票请求给其他节点
  • 如果自身状态是Leader的话,发生过期时间已经到达,就给其他节点发送心跳请求
  • candidate在发送投票请求时
    • term先自增1,刷新自己的过期时间
    • 给所有的peers发送投票请求,并统计获得的投票数,只要投票数大于半数,就可以成为Leader,成为leader之后,需要直接发送心跳请求(统计需要使用原子计数)
    • 期间如果收到了一个term比自身要大的请求,便将自身状态设置为Follower,标记本次选主失败,已经有更新的leader存在
  • leader发送心跳请求时
    • 先刷新自身的过期时间,准备下次心跳
    • 给所有peers发送心跳请求,如果收到一个term比自身大的响应,就设置自身的term,再回退到follower状态,刷新自身的过期时间
  •  在节点收到投票请求时,处理逻辑为
    • 比较自身的term与请求携带的term(对应candidate的term),如果自身的term比请求推荐的term大的话,将响应携带的term设置为自身的term,响应不投票,并结束
    • 如果自身的term比请求携带的term小,就把自身的term设置为请求携带的term,状态设置为Follower,并比较两方的日志状态(当前没有进行log操作,都是一样新的),设置自身的投票对象id,再刷新自己的过期时间
  • 在节点收到心跳请求时(log为空的log请求)
    • 先判断term大小,如果自身term比较大的话,设置响应的term为自身term,返回false
    • 否则将自身状态更新为Follower,投票对象设置为-1,自身term设置为请求携带的term,并更新过期时间,返回成功
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章