yzongyue / 6.824-golabs-2020

MIT 6.824 2020
416 stars 94 forks source link

lab 2c: 一个理论上可能存在的问题 #2

Open dreamerlzl opened 4 years ago

dreamerlzl commented 4 years ago

大致看了下源代码,感觉可能有以下问题: 当follower 1的election timer超时调用startElection()后,如果是rpc的RequestVote/AppendEntries先拿到锁并且发现有更大的term x, 那么follower 1会依然成为candidate并且term会是x + 1。那么一个刚当上leader的节点可能会被由follower转candidate的1替代掉,test的one()会失败。

如果理解错了,望谅解(我自己的lab 2当时卡在这里了)。

yzongyue commented 4 years ago

当follower 1的election timer超时调用startElection()后,如果是rpc的RequestVote/AppendEntries先拿到锁并且发现有更大的term x, 那么follower 1会依然成为candidate并且term会是x + 1。

这个是会存在的,这时候如果有 leader 节点的话,因为 follower 1 的 term 更高会有新的选举,直到选出新的 leader。 我的理解是,one 这个函数检查的是 Raft.Start 后 cmd/index 及 commit cmd 的 server 数量和期望的是否一致,但是这个判断并不十分合适,因为 raft 并不保证 Raft.Start 成功 cmd 一定被 commit,在网络变化的时候很容易出现新的选举,所以大部分 one 函数的调用 retry == true,为的是排除失败的情况。 如果 one 失败的话说明超时时间设置等问题导致选举不能很快结束。 我的代码只是尽量让选举快结束,从而使 one 不会失败,确实你说的情况有失败的可能

dreamerlzl commented 4 years ago

当follower 1的election timer超时调用startElection()后,如果是rpc的RequestVote/AppendEntries先拿到锁并且发现有更大的term x, 那么follower 1会依然成为candidate并且term会是x + 1。

这个是会存在的,这时候如果有 leader 节点的话,因为 follower 1 的 term 更高会有新的选举,直到选出新的 leader。 我的理解是,one 这个函数检查的是 Raft.Start 后 cmd/index 及 commit cmd 的 server 数量和期望的是否一致,但是这个判断并不十分合适,因为 raft 并不保证 Raft.Start 成功 cmd 一定被 commit,在网络变化的时候很容易出现新的选举,所以大部分 one 函数的调用 retry == true,为的是排除失败的情况。 如果 one 失败的话说明超时时间设置等问题导致选举不能很快结束。 我的代码只是尽量让选举快结束,从而使 one 不会失败,确实你说的情况有失败的可能

感谢作者答复,我也觉得one()不是很合理。

Gnosnay commented 4 years ago

大致看了下源代码,感觉可能有以下问题: 当follower 1的election timer超时调用startElection()后,如果是rpc的RequestVote/AppendEntries先拿到锁并且发现有更大的term x, 那么follower 1会依然成为candidate并且term会是x + 1。那么一个刚当上leader的节点可能会被由follower转candidate的1替代掉,test的one()会失败。

如果理解错了,望谅解(我自己的lab 2当时卡在这里了)。

是的 如果one没有设置retry=true,one 中Start的数据就没有办法被commit 但是从raft协议的角度来看 这个结果是可以接受的