sofastack/sofa-jraft

Question:为什么readLeader需要判断最后一条日志term?

zhou317 opened this issue · 4 comments

Your question

在readLeader时, 需要获取最后一条commit日志的term,检查是否等于当前任期。
如果不等于当前任期表示此 Leader 节点未在其任期内提交任何日志,拒绝只读请求。

if (this.logManager.getTerm(lastCommittedIndex) != this.currTerm) {

请问这一检查的目的是什么呢?

个人理解,无论是readIndex还是leaderLease,都能确保当前节点在读的时候是leader。
因此,该节点拥有所有的已经提交日志,这次读一定可以看到之前所有的写。

Environment

  • SOFAJRaft version:
  • JVM version (e.g. java -version):
  • OS version (e.g. uname -a):
  • Maven version:
  • IDE version:

raft paper 5.4.2 有描述原因,请参考论文

raft paper 5.4.2 有描述原因,请参考论文

理解了:
新leader在commit一条日志前,不能判断之前日志是否commit,所以根本无法确定commit index在那。

非常感谢。

readLeader需要判断最后一条日志term,但是这个判断是不是在 becameLeader中隐含地做了:
becomeLeader最后调用NodeImpl::ConfigurationCtx->flush:

this.confCtx.flush(this.conf.getConf(), this.conf.getOldConf());
,
在这个函数中会加一条日志。
这条日志commit,ConfigurationChangeDone->run才调用fsm->onLeaderStart。

这个信息应该能利用起来节省掉term的判断?

理了理逻辑(太久远的代码),似乎是可以的,但是优化掉 readLeader 中的 term 判断似乎不能带来多大收益,还是倾向于保留原有的逻辑