成员变更与配置变更
这个issues准备做成员变更与配置变更功能,在这里讨论设计与实现欢迎大家参与。
首先解决新节点上没有数据的问题 在新节点加入时,新节点上是不存在集群中日志的,可以将待加入集群的节点以learner的角色加入到集群中,待新节点日志同步跟上之后再将节点从learner角色转变为follower,如果一个节点直接以follower的角色 加入集群,则直接拒绝。
Joint Consensus成员变更主要分为4步 1、运维向Raft集群发起成员变更请求,当leader接收到集群成员变更请求后,首先生成一条Cold,new日志,同步给Cold和Cnew两个多数派。( 2、当Cold和Cnew都达成多数派后才能提交该日志,此后的日志也需要Cold和Cnew两个多数派都达到共识。 3、当Cold和Cnew日志提交后leader再向Cold和Cnew同步一条只包含Cnew的日志。 4、只需要Cnew中的节点达成多数派就可以提交此日志,此后的日志也需要在Cnew中达成共识。 5、不在Cnew中的日志自动下线。 细节 1、Cold,Cnew与Cnew日志何时生效? 对于leader节点来说接收到将配置变更请求时,就会将Cold,Cnew日志生效 对于follower来说成员变更日志持久化之后生效,不需要等待日志提交
特殊情况处理: 节点被删除后会收不到leader的心跳,当被删除的节点心跳超时后就会变更角色到Candidate,会在集群中发起RequestVote,这里的处理方式是如果节点没有超过选举超时时间,则直接忽略这个RequestVote。在节点退出集群后,停止其选举超时功能,对外提供只读。
如果是joint consensus成员变更,是不是以Learner角色加入这一步可以省略,在append Cold-new这条日志的时候,要成功append的话,会把之前的日志都同步过去。
如果是联合共识成员变多,是不是以学习者角色加入这一步可以省略,在append Cold-new这条日志的时候,要成功append的话,会把之前的日志都同步过去。
如果省去learner这一步,在2个节点的场景下节点加入集群后需要将之前的日志都同步到新节点中,会存在短暂的可用性问题,如果,如果强制要求只有learner才能加入到集群中的话,就可以解决这个问题了
感觉使用单节点添加的变更算法就足够了,联合共识算法似乎过于复杂,而且一个raft集群组往往也不会有太多节点。