sofastack / sofa-jraft

A production-grade java implementation of RAFT consensus algorithm.
https://www.sofastack.tech/projects/sofa-jraft/
Apache License 2.0
3.53k stars 1.12k forks source link

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

Closed zhou317 closed 7 months ago

zhou317 commented 7 months ago

Your question

在readLeader时, 需要获取最后一条commit日志的term,检查是否等于当前任期。 如果不等于当前任期表示此 Leader 节点未在其任期内提交任何日志,拒绝只读请求。 https://github.com/sofastack/sofa-jraft/blob/f84d40a04fdd8285aca048b26ba36a4df6745420/jraft-core/src/main/java/com/alipay/sofa/jraft/core/NodeImpl.java#L1566

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

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

Environment

fengjiachun commented 7 months ago

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

zhou317 commented 7 months ago

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

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

非常感谢。

zhou317 commented 7 months ago

readLeader需要判断最后一条日志term,但是这个判断是不是在 becameLeader中隐含地做了: becomeLeader最后调用NodeImpl::ConfigurationCtx->flush: https://github.com/sofastack/sofa-jraft/blob/2ea82d6d0605af737af59c853a3c00e643b0384e/jraft-core/src/main/java/com/alipay/sofa/jraft/core/NodeImpl.java#L1264 , 在这个函数中会加一条日志。 这条日志commit,ConfigurationChangeDone->run才调用fsm->onLeaderStart。

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

fengjiachun commented 7 months ago

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