raft协议学习记录

1. a leader cannot immediately conclude that an entry from a previous term is committed once it is stored on a majority of servers.

raft协议学习记录_第1张图片

  1. 在b阶段,S1下线,S5上线并被选为leader,同时写入term3/index2,此时S1和S2中的entry仍然是term2/index2。此时在多个实例中已经存在不同的entry,根据raft的定义,将来一定会有实例的entry被另一个(成为leader)实例的entry所覆盖。
  2. 到了c阶段,S5下线,S1上线并被选为leader,此时S1写入term4/index3(其实这个term4/index3是不是一个新entry并不重要,只是为了说明当前处于term4中),下面一步就到的问题的核心所在:S1将term2/index2 append到S3中,此时该entry已经到达了集群中的大多数,S1随即将其标记为commited(这里与上面截图说明不太一样,我理解其实到S4的时候问题已经暴露出来了,不需要阶段e)。这一步是有问题的,因为在S5中最新的entry是term3/index2,是要比term2/index2新的,只是S5暂时下线了。如果此时只对term2/index2进行commit,后续S5上线会用其term3/index2的entry覆盖掉其他节点已经被commit的term2/index2,因为S5的term较大
  3. 因此需要一条额外的逻辑,新leader在commit旧term的entry的时候,必须同时commit一条当前term的entry(可以是空),这样由于新leader的term一定是最大的,所以未来没有节点可以重写这个entry

2. Leader Completeness:if a log entry is committed in a given term, then that entry will be present in the logs of the leaders for all higher-numbered terms.

leader可以重写follower的entry,如果某entry被leader复制到集群中的大多数然后commit,为什么不存在该leader crash之后,新leader中entry与该leader存在冲突,然后重写follower中的entry的情况呢?
如果某entry被leader commit,说明其已经被复制到了集群的大多数,后续的leader一定得倒了这‘大多数’之一的投票,也意味着新leader的entry一定比大多数节点的entry「新」。又因为leader的entry是‘append only’的且entry永远只从leader流向follower,所以leader中的这条entry不会被重写,只会随着时间的推移而被commit

3. write snapshot时需要‘stop the world?’

4. 在leader响应client的请求,复制entry到大多数之后挂了(不管有没有应用到自己的状态机),client看到请求失败了,会重试,如何保证幂等?

每个来自client的req都有一个唯一的序列号,server端维护一个最近处理过的请求序列号集合,对于更新的req,首先看该req有没有被处理过,如果有,直接返回成功

5. candidate的意义是什么?只有follower和leader两个状态行不行?

随机选举超时的设计,意味着希望每次只有一个节点发起选举,并成为leader(最理想的情况),如果没有candidate状态,所有follower在超时后都会去竞争leader;而有了candidate状态,定义只有在这个状态下才会竞争leader,follower一旦将票投出去(没有投给自己),就不会再进入candidate状态。如果存在有资格成为leader(最新的log)的节点参与了竞选,那么自然不希望别的节点再来“搅局”

你可能感兴趣的:(分布式)