求助tinyky的project3b

lz在做这个project的时候发现AddNode命令创建的新节点需要接受一个快照实现数据同步,在这个创建节点的过程中,我发现了这样的问题:
snapshot似乎总是按照最新的Region配置产生,但是这个Region配置和Snapshot指向的meta.Index不在一个时间点,示意图在下面
index=14时只有节点1一个节点,index=15引入了节点2。节点2被创建后需要索取快照,节点1首先发了一个meta.Index=5, peers=[1,2,3,4,5]的快照 (这个测试用例初始五个节点,删除到一个节点后再新增节点),这个快照因为配置老旧被舍弃;然后节点1重新生成了个新的快照, 节点1向节点2发送了peers=[1,2]但是meta.Index=14的快照,我不理解为什么会发这样的快照。
我认为meta.index 应该是指这个快照包含的最后一个日志的index,它的配置应该是peers=[1]
是我之前的实验做的有bug嘛?

没看懂你想问什么…

看完一脸懵,楼主你打算是问什么

我觉得发送的snapshot中 “meta.Index=14但是peers=[1,2]” 有问题, 我认为 “index=14 时刻 peers=[1]”, peers=[1,2] 是index=15的AddNode这个entry应用后的结果。
我认为要么 meta.index = 15 且 peers=[1,2]; 要么 meta.index=14且peers=[1]
我认为meta.index = 14 但 peers=[1,2] 有问题

把对应的代码位置截个图发一下,我看看那附近的逻辑。


这里,这个validate函数要求了Snapshot需要包含最新的配置。
通过debug我发现snapshot中的meta.index与compactIndex不是一个值,我感到很奇怪

G,代码写错了 :innocent:,上面的debug问题是我代码的问题。
不过还是很好奇snapshot中的meta.Index和compactLog之间的关系,我注意到leader虽然发送了一个快照,但是它本身并没有把这个快照应用,把这个快照之前的日志截断

index标记的日志如果被compact了,就得重新发送快照了。

3b为什么这么难顶哇,测试用例是TestConfChangeRemoveLeader3B,又遇到一个匪夷所思的问题。
大概描述下我遇到的问题:
这个测试用例里的节点id和storeid相等

初始化一个节点配置为[1,2,3,4,5]的集群
经过若干次增加删除,增加删除节点
得到了一个节点配置为[5]的集群
然后增加一个节点节点配置变为[5,1]

然后测试用例就卡着了,我发现leader5一直在向follower1发送snapshot和heartbeat,但是节点1甚至都没被store1创建出来。store1也收不到消息。


问题大概是这样,请给我一些debug思路吧

tikv的处理里面,peer是在第一次收到心跳的时候创建出来的,batchsystem中如果对端的peer不存在,会发送control消息给store,store收到后创建peer,然后把刚才收到的消息发送给peer。

嗯嗯,谢谢。我感觉问题应该是在创建节点这里。
只有一个节点的时候进行添加节点命令,会直接达成共识并且apply;但是如果那个添加的节点一直起不来的话,Raft集群就不可用了,2节点配置需要2节点达成共识,另一个节点不上线的话无法达成共识。
Raft作者的博士论文Chap4里说是先进入Learner状态,保证添加的节点是可用的。再进行投票节点添加。
那么问题来了,tinykv的3b需要增加一个learner机制来通过这个测试用例嘛。

好像还是创建不出来,我在Propose之前先尝试发送了一次心跳,但是这个心跳被拒绝了,这是我的逻辑。
这里可以有什么办法主动创建一个节点嘛?


目的端拒绝的那里处理。我给你贴一下子tikv的代码位置, 这里 maybe_create_peer
https://github.com/tikv/tikv/blob/master/components/raftstore/src/store/fsm/store.rs#L2218