奇数和脑裂


最近看到下面这样一张谷歌 Borg 的架构图,无意中数了下 BorgMaster 的图块层数,发现是 5 层。

在这里插入图片描述

那么,值得思考的问题是: 为什么是 5 层呢 ? 可以是其他数量么? 可以是偶数么?


1、单点风险


所谓单点风险就是单服务实例运行所带来的风险。由于没有备份,那么如果这个实例挂了,就无法提供服务。
而对于任何服务器来说,都是存在故障的可能的,

因此生产环境中,应该尽可能避免单点风险。即类似于上图的 BorgMaster 这种服务节点,是不可能单例提供服务的。


2、最大容错


所谓最大容错,是指一个集群最多可以容忍死亡多少个实例。
假如只部署 2 个 zk 进程实例,当其中一个 zk 进程实例挂了后,那么剩下的那个进程实例并不能构成一个 quorum 的大多数。
因此 2 个 zk 进程实例构成的集群,其最大容错为 0 ,
而 1 个 zk 进程实例,其死亡容忍度自然也是 0,
这就意味着 ,2 个实例 和 1 个实例 的最大容错并没有区别。

另外,部署 2 个实例甚至比单点模式还更不可靠,因为 2 个实例其中一个不可用的可能性比 1 个实例不可用的可能性还大。

因此搭建 2 个实例的集群是不合适的。


3、节省资源


上面提到 2 个 zk 实例的最大容错是 0;
那么再推而广之,如果有 3 个 zk 实例,1 个死了,还剩下 2 个正常的,过半了,所以 3 个zk实例的最大容错是 1;
同理,4 个 zk 实例的最大容错也是1:

扫描二维码关注公众号,回复: 9027163 查看本文章
集群实例数 最大容错
1 0
2 0
3 1
4 1
5 2
6 2

… …

这样就会发现一个规律:2n 和 2n-1 的最大容错是一样的,都是 n-1,
所以在容错能力不变的情况下,从节省资源的角度看,2n-1(奇数)比 2n(偶数)更划算些。


4、脑裂问题


另外,前面 “最大容错” 部分,提到 “quorum的大多数” 。
从这个角度思考,其实会发现,为了在集群中顺利选举出 master/leader,
通常需要满足以下规则:可用节点数量 > 集群总结点数量/2

这具体是为什么呢?这就要从 “脑裂问题“ 说起了。

通常一个集群 ,比如 Etcd、ElasticSearch、Zookeeper 集群,
这些集群有一个统一特点:那就是它们通常会有一个 master 来管控集群,这个 master 可以认为是这个集群的大脑。

假设有一个集群里面只有两个节点,而且它们都知道需要在这个集群里选举出一个 master。
那么,当它们两个之间的通信完全没有问题的时候,则可以达成共识,选其中一个作为 master。
但是如果它们之间的通信出了问题,那么两个结点都会觉得现在没有 master 了,所以每个节点都把自己选举为 master,
于是这个集群里面就会出现两个 master。
这样集群就紊乱不可用了。

但是如果我们遵守上述规则进行选举的话,
即使出现脑裂,集群最多也只会出现一个可以提供服务的子集群(即能满足 “节点数量> 总结点数/2” 的子集群最多只会有一个)。

所以集群必须满足 ”可用节点数量 > 集群总结点数量/2 “ 的规则。

因此,从这个角度看,类似于上图的 BorgMaster 这种服务节点数,是不能设计为偶数的,偶数就容易出现脑裂问题。


5、容错和性能


那么,分析到这里,我们就知道,集群的服务节点数,应该是一个大于 1 的奇数了。
那么,这个奇数是不是越大越好呢?

以 ETCD 举例说明:

ETCD 使用 Raft 协议来保证各节点之间状态一致。
根据 Raft 算法原理,当节点数目越来越多的时候,会降低集群写性能;
这是因为每一次写操作,都需要集群中大多数节点将日志落盘成功后,leader节点才能修改内部状态机并将结果返回。
但是根据 ETCD 分布式数据冗余策略,集群节点越多,容错能力也越强。

所以,关于集群节点数量大小的优化,本质上其实是容错和性能之间的平衡取舍。

发布了37 篇原创文章 · 获赞 24 · 访问量 3098

猜你喜欢

转载自blog.csdn.net/weixin_44648216/article/details/103394045