[tinykv学习营]关于 NOOP 和 Vote 的疑问

在测试点中

func TestLeaderCycle2AA(t *testing.T) {
	var cfg func(*Config)
	n := newNetworkWithConfig(cfg, nil, nil, nil)
	for campaignerID := uint64(1); campaignerID <= 3; campaignerID++ {
		n.send(pb.Message{From: campaignerID, To: campaignerID, MsgType: pb.MessageType_MsgHup})

		for _, peer := range n.peers {
			sm := peer.(*Raft)
			if sm.id == campaignerID && sm.State != StateLeader {
				t.Errorf("campaigning node %d state = %v, want StateLeader",
					sm.id, sm.State)
			} else if sm.id != campaignerID && sm.State != StateFollower {
				t.Errorf("after campaign of node %d, "+
					"node %d had state = %v, want StateFollower",
					campaignerID, sm.id, sm.State)
			}
		}
	}
}

我们能发现,测试中依次触发 3 个结点的竞选.

  • 在 1 结点通过所有结点的选票竞选成功,成功后,1结点在日志中添加 noop ,日志长度为 1
  • 在 2 结点通过2、3结点的选票竞选成功,成功后,1结点在日志中添加 noop ,日志长度为 1
    由于 noop 日志只是在 becomeLeader 时 append 到 r.RaftLog.entries 中,且测试代码中并未触发由 leader 向 follower 的复制流程
    那么结点3收到 pb.MessageType_MsgHup 时,由于结点3的日志长度为0,无法获得 1、2的选票,无法竞选成功
    但我得出的结论与测试点明显不符,请问是哪里出错了呢?

是 noop 日志添加进 r.RaftLog.entries 后需要立刻向 follower 扩散吗?

1赞

添加后立即广播log就行了

1赞

tinykv中,将heartbeat和append分开。
所以每当Log发生变化(包括noop),就直接发送append
而tick时,heartbeat timeout后,即使有log需要发送,也只发送心跳

1赞

noop 日志直接广播到其他 Follower 节点就行。这时候已经存在 Leader 了,至于其他 Follower 节点怎么处理,就是日志复制的流程了。

1赞

十分感谢大家的回复

1赞