一 引言
二 成员变更
1 Joint Consensus成员变更
2 单步成员变更
三 两阶段成员变更的单步实现
-
通知节点在收到并持久化Cnew日志后从Cold,new配置切换到Cnew配置。
-
通知不在Cnew配置中的节点在Cnew日志提交后下线。 -
成员变更过程中发生Failover后,本地有Cnew日志的节点具有优先选举权。
1 ZooKeeper成员变更
为了让新节点追上最新数据,新成员配置S’中的新节点B3、B4先连接到当前的主节点P,P会向它们传输自己当前的状态作为他们的初始状态。在Zab协议中当备节点连接上主节点时这样的状态传输就会自动发生,并且会继续从主节点P接收所有后续的操作日志(例如图中的Op1和Op2),这个过程中节点B3、B4不参与投票。
主节点P向连接到它的所有备节点(S U S‘)发送成员变更日志COP,COP日志中携带旧成员配置S和新成员配置S‘,并等待旧成员配置S中的节点确认。一旦S中的多数派确认了COP日志,就对S’达成了共识。
在COP日志之前的日志只需要旧成员配置S中的多数派确认,可以在旧成员配置和新成员配置(S U S‘)中提交;在COP命令之后且在S’的激活消息ACTIVATE之前的日志需要新旧成员配置(S U S‘)两个多数派确认,并且只能在S’中提交;在S’的激活消息ACTIVATE后的日志,只需要在S‘中确认和提交。
主节点P等待COP日志以及S'中COP之前的日志的确认。
一旦新旧成员配置(S U S1)两个多数派都确认了COP日志,主节点P就提交COP日志,并广播一条激活消息ACTIVATE来激活新成员配置S’从而完成成员变更。与日志同步消息类似,ACTIVATE消息包含主节点P的Epoch,携带过时的Epoch的ACTIVATE消息将被忽略。
2 改进的单步实现
四 总结
五 思考
为什么Cold,new日志提交后,Cnew日志最终一定会提交?
使用ACTIVATE消息让节点切换到新成员配置后,如果节点重启,如何保证继续使用新成员配置?
两阶段成员变更的单步实现还有没有其它实现方法?