project2ab raft_paper_test TestFollowerAppendEntries2AB

test代码太长,不贴了。
在这个test里面,leader在发送appendMsg时,没有附加committed字段,所以默认committed=0。但是tests[2]中 收到消息的follower 的committed字段却不为0。请问应该如何理解这个样例?

1赞

Follower 的 CommitIndex 比 LeaderCommit 大,不会更新当前的值。

1赞

请问为什么会出现follower 的CommitIndex比leaderCommit大的情况

1赞

下面这是按照Raft论文逻辑来的。

由于commitIndex并没有写入到磁盘中,因此,每次宕机恢复之后都初始化为0。我们假设一个比较极端的情况。

Leader宕机之后又重新恢复,commitIndex重新初始化为0,这个时候如果收到客户端写日志的请求,那么Leader发送给多数节点的消息AppendEntries中commitIndex就是0,Follower收到这样的消息,并不会更新CommitIndex。

而Leader会在收到其他节点commitIndex的结果之后,按照多数原则更新自己的CommitIndex。

===========

但其实在tinykv中commitIndex是被持久化了的,写入到了HardState中,不会出现上面的情况。

如果不是0的话,也可能会出现收到了旧的消息,那也需要加上这个判断,没必要更新。

2赞

非常感谢。再请教一个问题,tests[2]中follower 的committed值为2是怎么得到的啊?是因为初始化的时候MemoryStorage.ents有两项吗?但是我看之前的test里,同样利用MemoryStorage进行初始化,之后再becomeleader,committed值为0。

1赞

MemoryStorage.ents有两项和commitIndex无关。

这个测试里面有提到committed==2吗?我好像没看到,能具体说一下嘛:joy:

1赞

测试里的 unstableEntries 函数的实现为 l.entries[l.committed:l.LastIndex()]。tests[2]中wents有两项,wunstable为空,说明committed值为2?

1赞

unstableEntries应该是l.entries[l.stabled:l.lastIndex()]。

unstable表示没有被持久化的位置,持久化应该比commitIndex位置大(或者相等)。

image

1赞

不好意思,犯傻了:joy:

1赞