《深入理解 Nacos 集群与 Raft 协议》系列

大家好,我是G探险者!

很多人部署 Nacos 集群时,会遇到这样一个问题:

我明明部署了 5 个节点,但只启动了 2 个,为什么系统完全无法使用?

这不是 Nacos 的 Bug,而是 Raft 共识算法的一个核心设计 ------ "过半存活原则"。

本篇我们将深入讲解:

为什么需要超过一半节点存活?

如果未过半,系统会发生什么?

如何从理论上理解这个约束?

一、Raft 的"过半投票原则"

Raft 在以下两个地方都要求"过半节点确认"才能推进:

选主(Leader Election):候选人需要获得超过半数节点投票才能成为 Leader

日志提交(Log Commitment):Leader 的日志条目,必须被超过半数节点确认,才能算"已提交"

这两个约束,是整个 Raft 一致性协议的核心。

→ 所以,没有过半节点存活,就选不出 Leader,无法提交日志,系统即不可用。

二、举例说明:三种典型节点数量

节点数

最小存活数(过半)

3

2

5

3

8

5

假设你部署了 8 个节点,只启动了 4 个,那就无法满足"超过 8/2 = 4"这个条件 → 系统无法进行任何写操作,甚至部分读操作也会失败(因为没有 Leader)。

三、为什么非得"过半"?

这是为了防止脑裂和数据丢失。

我们来思考一个问题:

如果 5 个节点中,A、B 两个节点单独启动,不满足过半,但系统仍允许它们工作,那会发生什么?

A 成为了 Leader,写入一条日志(仅 A、B 有)

突然 A、B 宕机,C、D、E 启动,C 成为新 Leader

C 重复写入了另一条日志(无 A、B 的写入)

→ 日志分叉!数据丢失!

为了避免这种情况,Raft 要求任何 Leader 的日志必须获得"过半副本确认",才能提交。

而一个节点想当选为 Leader,也必须能拿到过半选票。

所以,如果你活跃节点不满过半:

不能选主

原 Leader 无法继续领导(因心跳无响应)

所有提交机制暂停

→ 系统进入保护性停顿状态,而非错误工作。

四、Nacos 集群部署的建议

✅ 正确部署姿势

总节点数建议奇数(3、5、7、9),避免投票平票

启动时应确保至少过半节点在线,否则系统不工作

⚠️ 错误部署陷阱

部署 8 个节点,仅启动 4 个 → 失败

以为"部分可用" → 实则"不一致风险" → Raft 拒绝启动

五、可用性 vs 一致性

Raft 在设计时就做出了选择:

牺牲"部分可用性",换取"数据强一致性"

也就是说:

哪怕你能读取,但 Leader 不确定日志已同步 → 暂停处理

系统保证数据一致,而不是"不管三七二十一先返回"

这也是 Nacos、etcd、Consul 等注册中心使用 Raft 的原因:

配置信息必须强一致(否则灰度配置不生效)

服务列表变更必须可靠(否则服务发现错乱)

六、如何判断当前集群是否满足"过半"?

查看 Nacos 控制台日志或访问 /nacos/v1/ns/operator/raft/cluster 接口:

json

复制代码

{

"leader": "nacos-1",

"raftPeers": [

{"ip": "nacos-1", "state": "LEADER"},

{"ip": "nacos-2", "state": "FOLLOWER"},

{"ip": "nacos-3", "state": "FOLLOWER"},

...

]

}

如日志中出现:

text

复制代码

no leader is available now!

说明未能选主,系统已进入"挂起"状态。

七、总结

Raft 是为了保证数据一致性而牺牲了可用性的一种协议。

所有操作都要过半节点参与确认

未过半时,为防止脑裂,系统主动进入保护性不可用

在 Nacos 中体现为:Leader 无法选举、写请求挂起、读请求可能失败