关于proposal的消费逻辑以及可能带来的错误(tinykv)

raft层的代码,raft的论文讲的比较清楚,同时有etcd的参考,一般不会出很大的问题。但是server层没有对应的代码参考,同时也没有论证严谨的逻辑进行参考,因此会带来不小困难,而且有一些问题难以排查。下面是关于proposals中的消息的一些消费逻辑,我们给出来的思考:

  1. 只有Leader才会将上层的消息加入到proposals中;
  2. 当进行proposals的消费时,需要对entry.Index, entry.Termproposal.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相等,之后便可以沿用第二条的处理方案;
8 个赞

忽略了这里,测试OnePartition2B的时候,100次有2,3次出错,request time out, 怀疑有的request 一直没有response. 原来的逻辑是去proposes 数组中查找对应的index term, 匹配就返回,没有匹配的也没有处理。proposes数组元素返回后也没有删除。

1 个赞

有用的话给我点个赞哈哈

2 个赞

建议把链接发群里

1 个赞

在entry.Index < proposal.Index的时候,如果掠过不处理,原leader也没处理这条日志,现在的leader也没处理这条日志,那岂不是这条日志相当于是空的不起作用

不会啊,原Leader的proposal.Index又不会大于entry.Index

还有,我们说的不处理是不回应proposal的callback,而不是不处理日志,日志只要提交了都是要处理的。