raft相关问题

Raft的一致性复制过程

  1. 客户端向leader发送请求
  2. leader向自己的日志增加一条新entry,然后向所有的follower并行发送AppendEntries RPC来复制这条新entry。AppendEntries RPC可以一次性发送多条entry。
  3. follower通过AppendEntries RPC中的prevLogIndex和prevLogTerm查找本地是否拥有这条entry的前一条entry,如果有,则删除其后所有冲突的entry,然后添加新entry,向leader发送success响应
  4. 当leader接收到来自过半数follower的success响应时,则将这条entry标记为commited,并在随后发送的AppendEntries RPC中将最新的leaderCommit发送给所有follower
Read More

6.824 lab3b

设计思路

实验3b需要解决的问题:

如何判断snapshot的时机?

persister.RaftStateSize()返回已经持久化的raft日志(连同若干个需要持久化的变量)的大小。server持续调用该函数,当返回值等于maxraftstate的时候进行snapshot。需要处理maxraftstate==-1的情况。snapshot时还需要传入snapshot对应的最后一条raft日志的下标,需要多维护一个变量。

snapshot包含什么?

snapshot包含KV数据库的底层map和一些用于维护一致性的变量。当服务器重启时,Persister中保存的snapshot直接复制到server层即可。

maxraftstate是否需要持久化到Persister当中?

不需要,因为maxraftstateStartKVServer()的参数,在启动server时被传入。

当server从applyCh中读到snapshot时应该执行什么操作?

直接覆盖原有database即可。

如何保证指令的去重?

maxOpIndexs保存到snapshot当中,进行持久化。

Read More