raft 算法中的集群成员变更问题

本文深入探讨了 Raft 分布式一致性算法中的成员变更问题,包括为何需要成员变更、变更可能引发的脑裂问题,以及解决这些问题的联合共识和单节点变更两种方法。详细解析了每种方法的流程,确保在成员变更过程中避免数据不一致,保证集群的安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在上一篇文章《分布式一致性算法之 raft 图解》中我们讲解了 raft 算法的领导者选举以及日志复制的问题,同时通过一个具体实例讲解了 raft 是如何通过“一切以领导者”为准来解决日志不一致的情况的。同时在文章结尾笔者也讲到 raft 算法包含的内容远不止这么多,甚至上述的一些问题都是 raft 中的 base(基础)问题。接下来,我们将会用一篇文章来继续讲解 raft 需要解决的另外一个难题 – 成员变更问题。

为什么会有成员变更

首先我们要有一个常识:一台服务器不可能永远无故障地运行下去,即使服务器不会发生问题,那么也许是因为网络问题、亦或是集群本身的 bug,都有可能导致某个节点不可用。在这个时候,我们往往会选择新增一个或多个节点来替换掉不可用的节点,从而产生了成员变更。同时,一家公司的发展不可能永远不变,我们的业务规模也就不可能永远不变,这个时候,集群规模的变更也就是顺理成章的事情了。

也许有的同学会说,想要新增节点的话,那就直接新增好了,反正 raft 会通过日志一致性算法将新节点不存在的日志复制过去。但是事实果真如此吗?

成员变更会产生什么问题

不妨我们假设原始集群中有 3 个节点 A、B、C,它们当前的日志状态如下:

mc0.jpg

我们要意识到,基于日志复制“大多数”原则,上述的日志情况是完全有可能存在的,因为对于三节点的集群来说,最新的那条日志项已经被成功复制到了大多数集群,那么它便可用被领导者应用到状态机。

假设我们现在想要往集群中新增两个节点 D、E,大家可用想一下,假设我们直接将两个节点添加到集群中,会产生什么问题?

我们都了解到 raft 算法具有领导者唯一性,这是实现数据一致性的首要保证,一旦集群中有两个领导者节点,那么将会产生及其严重的数据不一致,这显然对于保证严格一致性的 raft 算法是无法接受的。而像上述那样直接添加两个节点,由于每个节点新旧配置更新的时间不同,导致在某一时刻可能存在新旧配置两个大多数情况的存在,便很有可能使集群发生“脑裂”,也就是出现两个领导者。比如在进行成员变更的时候,节点 A 和 B、 C 产生了网络分区,如果此时新增的节点 D、E 和 A 在同一个分区,那么对于新配置中的领导者 A 而言,集群中依然有大多数节点在正常运行,它依然是领导者,而对于维护了旧配置的节点 B、C 来说,由于接收不到领导者的心跳请求,那么通过领导者选举算法,节点 B 会变成此分区的领导者,此时,整个集群中便产生了两个领导者,分别是节点 A 和节点 B:

脑裂.jpg

当然,以上是针对往集群中添加节点的情况,其实从集群中同时移除多个节点也同样会发生上述问题,这个大家不妨按照相同的思路来自己推理一下(提示:从 5 节点集群中移除两个日志相对完整的节点)。

因此通过上面的分析我们可以发现,当新增多个新的节点的时候,我们不能直接将所有新节点添加到集群中。

那么有没有什么办法可以解决上述问题呢?

解决成员变更问题

raft 解决成员变更问题主要有两个方法,分别是联合共识算法和单节点变更算法。

方法一 – 联合共识(Joint Consensus)

联合共识算法是 raft 作者首先提出的一种方法。此方法允许一次性向集群中插入多个节点而不会出现脑裂等 (safety) 问题,并且整个集群在配置转换的过程中依然能够接收用户请求,从而实现配置切换对集群调用方无感知。

在联合共识阶段,集群工作需要考虑到新旧两种配置,具有如下约束或者约定:

  • 约定一:日志会被复制到新老配置的所有节点;
  • 约定二:新老配置的节点都可以被选举为领导者;
  • 约定三:选举和日志复制阶段需要在新老配置上面都超多半数才能被提交生效。

下图是官方论文中出现的图,代表联合共识阶段配置变更的时间线:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值