raft层的代码,raft的论文讲的比较清楚,同时有etcd的参考,一般不会出很大的问题。但是server层没有对应的代码参考,同时也没有论证严谨的逻辑进行参考,因此会带来不小困难,而且有一些问题难以排查。下面是关于proposals中的消息的一些消费逻辑,我们给出来的思考:
- 只有Leader才会将上层的消息加入到
proposals
中; - 当进行proposals的消费时,需要对
entry.Index, entry.Term
与proposal.Index, proposal.Term
进行分类情况讨论:
- 如果
entry.Index == proposal.Index && entry.Term == proposal.Term
: 直接回应proposal中的消息,我们是可以根据index与term唯一确定一条消息的,当这里可以对应的时候,我们需要正确回应这条消息; - 如果
entry.Index == proposal.Index && entry.Term != proposal.Term
: 首先本条消息需要返回一个err,index相同而term不同,说明上一条对应index 的消息未能达成同步,但是不能直接结束,而应该继续向后搜索proposal,直到将该Index的消息全部处理或者处理到entry.Index == proposal.Index && entry.Term == proposal.Term
,至于为什么处理到这里可以结束,因为既然该Index的消息在此Term达成共识,那就不会出现相同Index而有更高Term的消息了,proposal中的消息按照index从小到大,他们的proposal.Index, proposal.Term
都是单调不减小的; - 如果遇到
entry.Index < proposal.Index
, 说明了此时这些entry不应该在这个节点进行处理,这是一些前Leader留下来的信息。因此直接掠过不做处理,一直到Index相等,然后沿用上一条的处理方案; - 如果遇到
entry.Index > proposal.Index
,这里说明proposal中有一些被抛弃了的消息,因此需要直接对这些消息返回Err,直到index相等,之后便可以沿用第二条的处理方案;