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