Skip to content

Commit

Permalink
raft 成员变更
Browse files Browse the repository at this point in the history
  • Loading branch information
isno committed Dec 5, 2023
1 parent df96ce1 commit 38f7b16
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 4 deletions.
1 change: 1 addition & 0 deletions .vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ export default defineUserConfig({
'/consensus/raft-leader-election.md',
'/consensus/raft-log-replication.md',
'/consensus/raft-safety.md',
'/consensus/raft-ConfChange.md',
]
},
'/consensus/conclusion.md',
Expand Down
Binary file added assets/raft-ConfChange.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/raft-single-server.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions consensus/raft-ConfChange.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 6.4.4 成员变更

笔者前面讨论的部分假设的条件是 Raft 集群成员恒定不变,单实际上,我们会遇到很多需要改变数据副本数的情况,例如服务器故障需要移除副本,也就是说集群成员是需要动态变更的。

成员变更也是一个一致性问题,即所有节点对新成员达成一致,直接向 Leader 节点发送成员变更请求,Leader 同步成员变更日志,达成多数派之后提交,各节点提交成员变更日志后从旧成员配置(Cold)切换到新成员配置(Cnew)。但成员变更的一致性存在一个特殊性,

因为各个节点提交成员变更日志的时刻可能不同,造成各个节点从旧成员配置(Cold)切换到新成员配置(Cnew)的时刻不同。可能在某一时刻出现 Cold 和 Cnew 中同时存在两个不相交的多数派,进而可能选出两个 Leader,形成不同的决议,破坏安全性。

<div align="center">
<img src="../assets/raft-ConfChange.png" width = "350" align=center />
<p>成员变更的某一时刻 Cold 和 Cnew 中同时存在两个不相交的多数派</p>
</div>

如上图所示,3 个节点的集群扩展到 5 个节点,直接扩展可能会造成 Server1 和 Server2 构成老成员配置的多数派,Server3、Server4 和 Server5 构成新成员配置的多数派,两者不相交从而可能导致决议冲突。

由于成员变更的这一特殊性,一次成员变更不能当成一般的一致性问题去解决。为了解决这个问题,Raft 提出了两阶段的成员变更方法 Joint Consensus。

使用单节点变更方式很容易枚举出所有情况,如下图所示,穷举集群奇/偶数节点下添加和删除一个节点的情况,如果每次只增加和删除一个节点,那么 Cold 的 Majority 和 Cnew 的 Majority 之间一定存在交集,也就说是在同一个 Term 中,Cold 和 Cnew 中交集的那一个节点只会进行一次投票,要么投票给 Cold,要么投票给 Cnew,这样就避免了同一 Term 下出现两个 Leader。

<div align="center">
<img src="../assets/raft-single-server.png" width = "550" align=center />
<p>穷举集群添加节点的情况</p>
</div>

6 changes: 2 additions & 4 deletions consensus/raft.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ Paxos 算法描述与工程实现之间存在巨大的鸿沟,最终实现的
Raft 的本意是 R{eliable|plicated|dundant} And Fault-Tolerant(可靠、复制、冗余和容错),组合起来的单词 raft 有筏的含义,隐喻这是一艘可以帮助你逃离 Paxos 小岛的救生筏(Raft)。
:::

如果一句话总结 Raft,笔者觉得可以这样定义:从本质上说,Raft 是通过实现以强 Leader 为准的方式实现的一系列值的共识和各个节点日志的一致。Raft 算法的所有节点中会有一个节点作为领导者(Leader),其他非 Leader 节点被称为跟随者(follower)。leader 负责接收客户端的请求,根据请求生成日志并把日志复制到所有的节点中,这个过程我们称为复制过程
如果要用一句话总结 Raft,笔者觉得可以这样定义:**从本质上说,Raft 是通过一切以强 Leader 为准的方式实现的一系列值的共识和各个节点日志的一致**。这句话比较抽象,有点不太好理解,笔者再举个例子:Leader 就是 Raft 算法中的 “霸道总裁”,霸道总裁一贯的做法是“你们别说话,都听我的”,Raft 用这种方式决定了日志中命令的值,也实现了各个节点日志的一致

除了复制过程,如果 Leader 发生宕机等异常情况,其他节点需要成为新的 Leader,继续履行 Leader 的职责,我们将这个过程称为选举过程。

此外,在选举
Raft 算法论文中包含领导者选举、日志复制、成员变更几个核心,在本节,笔者以这几个核心问题为线索讲解 Raft 算法的原理。

0 comments on commit 38f7b16

Please sign in to comment.