分布式节点个数为什么通常是奇数个?
作为一名研发工程师, 在我的日常工作中经常涉及到各种分布式系统, 例如: ETCD, Redis, k8s 等. 这些分布式集群在部署的时候我们通常将节点的数量设置为奇数个, 这似乎是一个约定俗成的规则. 但是为什么? 除了偶数节点容易出现投票平票的情况是否还有其他的原因?
如果对分布式共识算法不太了解的话, 可以先阅读 Raft 协议详解.
在 Raft 协议中即便某些节点出现故障, 集群也可以达成一致. 那么在投票的过程中要求必须达到 大多数 节点的同意. 这时候我们可以得出一个 Quorum 公式:
Quorum=(N/2)+1
我们根据这个公式可以计算出下面这个表格. 很容易发现, 当我们使用偶数个节点的时候其实我们使用更少个的奇数节点也可以达到同样的容错能力.
集群大小 | Quorum | 可容忍宕机的节点数 | 容错能力 |
---|---|---|---|
3 节点 | 2 | 1 | 高 |
4 节点 | 3 | 1 | 没有提升 |
5 节点 | 3 | 2 | 更高 |
6 节点 | 4 | 2 | 没有提升 |
7 节点 | 4 | 3 | 非常高 |
显然, 当使用奇数个节点时我们会获得以下益处.
- 最大化容错
- 在 3 节点集群中, 1 个节点可能会发生故障, 其余 2 个节点仍构成仲裁.
- 在 5 节点集群中, 2 个节点可能会发生故障, 其余 3 个节点仍构成仲裁.
- 避免脑裂情况
- 在节点数为偶数(例如 4 个)的情况下, 如果一半的节点发生故障(2 个节点), 则剩余的 2 个节点无法形成多数, 从而导致系统无法确定哪一侧是正确的裂脑场景.
- 奇数消除了相等拆分的可能性.
- 效率
- 使用奇数可以最大限度地减少实现更高容错能力所需的节点数.
- 添加超出必要数量的节点会增加复杂性, 而不会产生成比例的好处.
那么是否意味着我们一定要使用奇数个节点呢? 不是的. 我们更加推荐奇数个节点通常是因为奇数个节点可以使用更少的节点达到同样的容错能力.