etcd集群成员变更

482 阅读2分钟

etcd集群在运行过程中,难免出现替换节点、新增节点、删除节点的需求,对于raft这种基于quorum机制的算法而言,实际生产环境,很难让节点在同时感知到集群节点的变化,正如raft[1]第6节,cluster membership changes呈现的场景,在一个三节点集群中新增两个新节点,就有可能出现脑裂。

针对raft集群的节点变更,raft算法提供了两阶段算法:joint consensus,这里直接贴上raft论文图文描述,如下:

当集群节点需要变更时,Leader节点会创建一份C old-new配置,并作为日志Entry同步到其他节点,日志Entry只要在节点上被存储下来,就会使用C old-new做决定,也就是说日志Entry的committed及选举投票都需要同时满足新旧配置的quorum,在C old-new被提交之后,Leader会创建一条C new作为新的日志条目拷贝到大多数,提交后使C new单独生效。

etcd实现与raft原文描述的_joint consensus略有不同,_对于单次变更的节点数量不同,etcd的实现也不同,主要有两种情况:单节点、多节点。

单节点变更流程

_etcd会将配置作为单独的日志Entry,配置Entry的类型为_EntryConfChange,配置Entry会复用普通日志Entry的append-committed流程,在配置被apply时直接进入生效阶段。

多节点变更流程

etcd会将配置作为单独的日志Entry,配置Entry的类型为_EntryConfChangeV2,配置Entry会复用普通日志Entry的append-committed流程,在配置被apply时直接进入joint consensus阶段,此时etcd节点使用C old-new配置做决策,然后Leader会创建一个空_EntryConfChangeV2日志Entry,将空日志Entry拷贝到其他节点,在空Entry被apply时结束joint consensus阶段,正式使用新配置做决策。

参考

  1. [^](zhuanlan.zhihu.com/p/385009425…](raft.github.io/raft.pdf)