Comments (19)
@LovesAsuna
“conflictIndex赋值到nextIndex也没什么问题” 这对conflictIndex的理解有点问题。
conflictIndex就是指的Follower的log中,在PrevLogIndex的前面 第一个 与 ConflictTerm 不一样的点。
这个信息返回给Leader后,Leader知道他前面有多少个一样的Term了,这样回退nextIndex的时候就相当于知道Follower前面的Log了。
其实如果Follower能够直接把它的Log中的Term都返回给Leader,然后Leader肯定能直接找到回退点,不需要一次RPC回退一下。
而这个机制相当于使用游程编码,使得传输成本更低。
这种方法在冲突Index的term都是一样的情况下比较高效(比如发生了split brain,其中一个小组的leader一直在接受客户端命令,假设1w条,这些命令都是在一个Term中,但是又不会被执行,最终需要网络恢复后删除掉),paper里也说了这不是必要的,但是不实现就通不过test
from mit6.824-2021.
conflictIndex不就是由follower计算出来的吗?leader用这个计算出来的值不就可以达到快速回退的目的了?
from mit6.824-2021.
但是leader不一定要回退到conflictIndex,从conflictIndex到PrevLogIndex中,如果有一个点对上了就可以回退到那个点
from mit6.824-2021.
冲突之后的日志不是要截断?
from mit6.824-2021.
是的
from mit6.824-2021.
那follower截断conflictIndex之后的日志,leader直接用conflictIndex作为nextIndex不就可以把日志一次性发给follower了
from mit6.824-2021.
conflictIndex不等于要回退的位置。
比如Follower的log里有1w个Term为2,而Leader有9999个Term为2的、其他的都是Term为3的,当PrevLogIndex==1w时
在验证第1w个log的时候发现冲突,Follower告诉Leader前面还有多少个Term为2的(conflictIndex=0),然后Leader就在自己的log里面从后往前比较,然后发现第9999个log的Term就是2,然后nextIndex就只用回退一位。
这显然不需要回退到0,那样还得重发这1w条数据。
from mit6.824-2021.
这里可能是我的理解不一样,在我的实现里是把conflictIndex就设为1w,follower截断1w之后的数据,然后leader设置nextIndex就设为conflictIndex的1w,然后把日志发送给follower
from mit6.824-2021.
那这样每次rpc只回退一个单位test2B的“leader backs up quickly over incorrect follower logs”可能过不了
from mit6.824-2021.
不是回退一个单位,就是直接回退到conflictIndex,因为我的设计里conflictIndex不是一个长度,就是一个具体的索引位置
from mit6.824-2021.
第一个conflictIndex就是冲突位置,第二个则是冲突位置的前一个,这里的设计是否有错误?
这里要怎么理解?
我自己对handleAppendEntries的实现是这样的
from mit6.824-2021.
不需要直接回退到conflictIndex,可以看看这段代码,结合test2B“leader backs up quickly over incorrect follower logs”的Log理解
https://github1s.com/s09g/raft-go/blob/HEAD/src/raft/append_entry.go#L73-L84
from mit6.824-2021.
主要理解几个问题
- conflictIndex不是冲突的位置。Follower都不知道Leader的整个Log,怎么知道这个位置是冲突的?有没有可能这个位置甚至后面一部分Leader不冲突?
- conflictIndex说明在[conflictIndex,PrevLogIndex]这段区间内,Follower的Term是相同的
- Leader需要判断自身的Log,如果在[conflictIndex,PrevLogIndex]中存在一个Term == ConflictTerm的Index,那必然前面的也相同,回退到Index。否则回退到conflictIndex(就是上面链接那段做的事)
from mit6.824-2021.
主要是实现不太一样,我参考的是这个仓库owner的实现;我看你的实现是按照课上Robert教授的方法来的(Xterm、XIndex、XLen)。有点不好统一起来,仓库owner没给出handlerAppendEntries的实现,很多东西要边看论文边猜出来
第一个conflictIndex就是冲突位置,第二个则是冲突位置的前一个,这里的设计是否有错误?
这个始终没理解
from mit6.824-2021.
按自己理解大胆改就完事了,我写的时候也看了别人的,但是最后还是按照我自己的想法实现的,通过testcase说明差不多就对了
from mit6.824-2021.
不过改的时候不确定的话先记录一下位置,方便后面debug重点看
from mit6.824-2021.
from mit6.824-2021.
if !rf.matchLog(args.PrevLogTerm, args.PrevLogIndex) { reply.Term, reply.Success = rf.currentTerm, false lastIndex := rf.getLastLog().Index if lastIndex < args.PrevLogIndex { reply.ConflictTerm, reply.ConflictIndex = -1, lastIndex+1 } else { firstIndex := rf.getFirstLog().Index reply.ConflictTerm = rf.logs[args.PrevLogIndex-firstIndex].Term index := args.PrevLogIndex - 1 for index >= firstIndex && rf.logs[index-firstIndex].Term == reply.ConflictTerm { index-- } reply.ConflictIndex = index } return }这一段中,如果follower与leader的日志不匹配,可以将conflictTerm和conflictIndex给到leader,让leader快速回退到冲突位置,而不需要递减index。这里的两种情况:
- follower日志过短,跟不上follower日志
在这里conflictTerm设置为-1,conflictIndex设置为follower最后一条日志的index+1- 正常的冲突
这里将conflictTerm只设置为要同步日志的任期,按我的理解,如果已经同步的位置到这个位置中间有有多个不同的任期,这里还是需要进行等同不同任期数量次数的请求才能到同步点的后一个位置
然后这里我不懂的是这里设置conflictIndex为index,在for循环中,退出条件是term != conflictTerm,当这里已经到同步点后的任期时,这里退出循环时index就会等于同步点的index这里两种情况,第一个conflictIndex就是冲突位置,第二个则是冲突位置的前一个,这里的设计是否有错误?
另外我想参考一下handleAppendEntriesReply的具体实现,因为我感觉conflictTerm好像并没有起到什么实际作用,可以直接将conflictIndex赋值到nextIndex也没什么问题(按照conflictIndex就是冲突位置的逻辑)
我觉得都可以,使用前一个也能保证正确。处理冲突时只传递confict Index也可以过测试。我的处理就是拿匹配term的第一个index发送的,接收端设置到NextIndex。
if rf.getLastIndex() < args.PrevLogIndex {
reply.Success = false
reply.XIndex = rf.getLastIndex()
// maybe snapshot, so not Adding 1
// snapshot increase and you should grap this.
return
}
if rf.getLogTermWithIndex(args.PrevLogIndex) != args.PrevLogTerm {
reply.Success = false
xTerm := rf.getLogTermWithIndex(args.PrevLogIndex)
for index := args.PrevLogIndex; index >= rf.lastSnapshotIndex; index-- {
if rf.getLogTermWithIndex(index) != xTerm {
reply.XIndex = index + 1
break
}
}
return
}
from mit6.824-2021.
发送端和接收端只要协调好的话应该有很多种方案的
from mit6.824-2021.
Related Issues (20)
- 大佬,求一份代码实现 HOT 1
- 求一份源码 HOT 1
- 求一份源码 HOT 1
- 求一份源代码 HOT 1
- 求一份源代码 HOT 1
- 求一份源代码
- AppendEntries和handleAppendEntriesResponse中,response.Term=0的情况 HOT 1
- 求一份源代码 HOT 1
- 求源码 HOT 1
- 关于日志复制的一点问题 HOT 1
- 求源码 HOT 1
- 求一份源码学习 HOT 1
- 你好,可以发一份源码吗?我有些地方不太明白。[email protected] HOT 1
- 求源码 HOT 8
- Lab2 的日志复制线程模型可能会导致 2D Test 超时 HOT 1
- 大佬求发一份源码!快被这个项目搞奔溃了 HOT 2
- follower 拒绝过期 SnapShot 导致 follower 日志过长 HOT 2
- 请教大佬,在2B日志复制中,具有相同日志的节点中,大部分都已经commit并提交了,但是碰巧暂时没有提交的竞选成功。 HOT 3
- 大佬,请问lab4b中一个raft节点就有一个shardkv吗?比如一个group组,下面有一个raft集群,共有5个raft节点,则共有5个shardkv,但是只有一个leader节点的shardkv对外提供服务吗? HOT 3
- 请教一下关于 leader 选举的问题 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mit6.824-2021.