问题描述:
在Pro2ab的Test中:TestLeaderElectionOverwriteNewerLogs2AB,进行集群newNetworkWithConfig(entsWithConfig…)初始化的时候,entsWithConfig中会调用newRaft初始化一个节点,我在newRaft中没有指定state==Follower,然后使用raft.becomeFollower(raft.Term, None)函数重置该节点状态,这个函数becomeFollower中会生成一个随机electionElapsed,会导致这个Test案例无法通过。
换言之,如果我在newRaft中,直接指定state为Follower则不会出现这种状态。
Pro2aa和Pro2ab目前只有这个案例有问题,自己的解决方式,就是直接指定,不随机生成electionElapsed
我在疑惑是我初始化的方式不对吗?不需要随机给一个electionElapsed吗?
1 个赞
Raft 中每个节点最开始的状态就是Follower,在newRaft中初始化为Follower没有问题。
使用raft.becomeFollower(raft.Term, None)函数重置该节点状态,这个函数becomeFollower中会生成一个随机electionElapsed,会导致这个Test案例无法通过。
不太清楚你说的这个不会通过是什么结果,超时吗?
成为Follower不需要经过一个electionElapsed的时间,这个是成为Candidate需要等待的时间。
1 个赞
如果我按照随机生成一个electionElapsed的方式去初始化节点和这个集群,这个案例是过不去的,我debug的时候,发现应该有投票的记录,但是没有,只有改动了这个随机时间的问题,就不会存在上述问题,这个案例也会通过
1 个赞
TestLeaderElectionOverwriteNewerLogs2AB:
n.send(pb.Message{From: 1, To: 1, MsgType: pb.MessageType_MsgHup})
sm1 := n.peers[1].(*Raft)
// 这里会出错,这里正确的结果是node1不会当选leader,但是我在使用electionElapsed随机化初始
化的时候,会导致上面的send中 其它节点会投票给node1,从而当选leader
if sm1.State != StateFollower {
t.Errorf("state = %s, want StateFollower", sm1.State)
}
if sm1.Term != 2 {
t.Errorf("term = %d, want 2", sm1.Term)
}
1 个赞
正确给Node1投票的方式是:2 V,3 X,4 X, 5 X
如果我这里使用electionElapsed随机初始化raft节点的状态,投票就会变成:2V,3X,4V,5V,从而node1当选leader,无法通过案例
1 个赞
我感觉这不太像随机的初始化时间问题。因为这个测试发起投票的消息是"手动"添加的。
可能存在的问题:
-
每个节点的Term、Vote是否正确地初始化了。需要看一下其他节点为什么能够投票?(本来应该是term相等,已经投票给其他节点了,因此拒绝投票)。
n := newNetworkWithConfig(cfg,
entsWithConfig(cfg, 1), // Node 1: Won first election
entsWithConfig(cfg, 1), // Node 2: Got logs from node 1
entsWithConfig(cfg, 2), // Node 3: Won second election
//这里初始化的时候Term=2,不可能再次投票给Candidate(Node1)了。。。
votedWithConfig(cfg, 3, 2), // Node 4: Voted but didn’t get logs
votedWithConfig(cfg, 3, 2)) // Node 5: Voted but didn’t get logs
-
真的是electionElapse有问题(虽然不太可能),可以是初始化为baseElectionTimeout+rand(baseElectionTimeout)。
4 个赞
我目前改了这里,所以就通过了,有疑惑不知道出问题的具体点在哪里。
这里需要再debug看看
1 个赞
system
(system)
关闭
9
此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。