project2ab的TestLogReplication2AB

我理解的,follower的commit index应该落后于leader的commit index。leader propose一条entry后,2个follower复制成功,leader commit index + 1, 可是为什么测试用例里follower的commit index 也 expect 加1呢,难道是中间遗漏了什么逻辑?没想明白。

确实遗漏了,leader commit index + 1之后,还需要告诉其他peers:leader commit + 1了, 你们的commit index 也要同步到leader上来。
超过半数的append成功之后,leader更新自身的commit,并且再次发送append同步commit index

leader在判断收到半数的append回复后需要更新commit,并且广播给peers,同步commit

2赞

在partA的文档的hint部分有提到一旦commit增加,会广播给所有follower

1赞

你的问题是什么?

我先前没注意到这个提示,因为论文中并没有这个设计,测试失败感到很困惑。现在豁然开朗了…

补充:在某些测试中,leader 广播 AppendEntries RPC 得到了多数结点复制成功的响应,按照论文的设计,此时 leader 结点的 committedIndex 将变更。

若不进行通信,follower 结点的 committedIndex 实际上是不会立刻变更的。

但是在 TinyKv 中不是这样设计的,从测试断言中可以得出 leader 结点的 committedIndex 变更后需要主动广播这个消息:

		wCommit := uint64(2 + tt.successCnt) // 2 elctions
		if sm2.RaftLog.committed != wCommit {// leader
			t.Fatalf("#%d: expected sm2 commit: %d, got: %d", i, wCommit, sm2.RaftLog.committed)
		}
		// ASK: if no any extra communicate, why assert follower committedIndex would be updated?
		if sm3.RaftLog.committed != wCommit {// follower
			t.Fatalf("#%d: expected sm3 commit: %d, got: %d", i, wCommit, sm3.RaftLog.committed)
		}

实际上在论文中提到的几种 RPCs 里面,无论是 Heartbeat 还是 AppendEntires 此时都不太适合做这件事情,特别是 Heartbeat,因为它的接收对 follower 结点可能意味着新一轮竞选的结束。如果使用 AppendEntires RPC 来同步 committedIndex 变更,这就要求实现 sendAppend() 时允许发送空的 entries。希望这个补充能够帮助到和我先前有着一样困惑的同学。