sofastack / sofa-jraft

A production-grade java implementation of RAFT consensus algorithm.
https://www.sofastack.tech/projects/sofa-jraft/
Apache License 2.0
3.56k stars 1.14k forks source link

选举问题咨询 #993

Closed LinHuiG closed 1 year ago

LinHuiG commented 1 year ago

我注意到jraft里有一个接口可以设置选举的优先级(NodeOptions.setElectionPriority) 如果我有A、B、C三个节点,我将C节点配置为NotElected(0),这意味着C节点永远不会进入候选状态 假设有以下场景:A节点作为主节点,日志有1 2 3 4 5 6条,C节点作为从节点日志也有1 2 3 4 5 6条,这六条日志应该是commit状态。而B节点日志只有1 2 3 4条。这时候当A节点宕机,而B节点日志少于C节点无法成为领导者,C节点选举优先级为NotElected,是否意味着集群无法选举出领导者,集群失活。

fengjiachun commented 1 year ago

是的,如果你想让一个节点完全不参与选举,就需要接受这种极端情况(最大 index 日志的多数派节点除了它全部挂了,它会拒绝所有选举投票),此时数据没丢,但是集群无法再提供服务。 NotElected 一般很少用,比如一个冷备机房的节点你不想它参与选举

LinHuiG commented 1 year ago

是的,如果你想让一个节点完全不参与选举,就需要接受这种极端情况(最大 index 日志的多数派节点除了它全部挂了,它会拒绝所有选举投票),此时数据没丢,但是集群无法再提供服务。 NotElected 一般很少用,比如一个冷备机房的节点你不想它参与选举

我测试了一下,发现设置为NotElected 的节点被选举为领导者了,集群正常运行==

fengjiachun commented 1 year ago

是的,如果你想让一个节点完全不参与选举,就需要接受这种极端情况(最大 index 日志的多数派节点除了它全部挂了,它会拒绝所有选举投票),此时数据没丢,但是集群无法再提供服务。 NotElected 一般很少用,比如一个冷备机房的节点你不想它参与选举

我测试了一下,发现设置为NotElected 的节点被选举为领导者了,集群正常运行==

那就是你设置问题

https://github.com/sofastack/sofa-jraft/blob/master/jraft-core/src/main/java/com/alipay/sofa/jraft/core/NodeImpl.java#L658

LinHuiG commented 1 year ago

是的,如果你想让一个节点完全不参与选举,就需要接受这种极端情况(最大 index 日志的多数派节点除了它全部挂了,它会拒绝所有选举投票),此时数据没丢,但是集群无法再提供服务。 NotElected 一般很少用,比如一个冷备机房的节点你不想它参与选举

我测试了一下,发现设置为NotElected 的节点被选举为领导者了,集群正常运行==

那就是你设置问题

https://github.com/sofastack/sofa-jraft/blob/master/jraft-core/src/main/java/com/alipay/sofa/jraft/core/NodeImpl.java#L658

这个函数我断点进去看了,确实是返回false,也确实选举成功了 还有一个问题,cliService.getAlivePeers拿到的peerIdList中所有的peerId.getPriority()返回都是-1..

fengjiachun commented 1 year ago

https://github.com/sofastack/sofa-jraft/blob/master/jraft-core/src/main/java/com/alipay/sofa/jraft/core/ElectionPriority.java#L29

LinHuiG commented 1 year ago

https://github.com/sofastack/sofa-jraft/blob/master/jraft-core/src/main/java/com/alipay/sofa/jraft/core/ElectionPriority.java#L29

我是使用ElectionPriority.NotElected设置的优先级 我的代码逻辑与发生的情况是这样的: A.setElectionPriority(1000); B.setElectionPriority(1000); C.setElectionPriority(ElectionPriority.NotElected);

A.start C.start ==A选举为leader A写入raftTask成功

A.stop Thread.sleep(3000); ====C节点进入NodeImpl.handleElectionTimeout并被allowLaunchElection返回false B.start ====C节点直接onLeaderStart了,没有再次进入NodeImpl.handleElectionTimeout C写入raftTask成功