一、容灾

所谓容灾,在IT行业通常是指我们的计算机信息系统具有的一种在遭受诸如火灾、水灾、地震、断电和其他基础网络设备故障等毀灭性灾难的时候,依然能够对外提供可用服务的能力。

对于一些普通的应用,为了达到容灾标准,通常我们会选择在多台机器上进行部署来组成一个集群,这样即使在集群的一台或是若干台机器出现故障的情况下,整个集群依然能够对外提供可用的服务。

而对于一些核心应用,不仅要通过使用多台机器构建集群的方式来提供服务,而且还要将集群中的机器部署在两个机房,这样的话,即使其中一个机房遭遇灾难,依然能够对外提供可用的服务。

上面讲到的都是应用层面的容灾模式,那么对于 ZooKeeper这种底层组件来说,如何进行容灾呢?讲到这里,可能不少读者会有疑问,ZooKeeper既然已经解决了单点问题,那么为什么还要进行容灾呢?

二、单点问题

单点问题是分布式环境中最常见也是最经典的问题之一,在很多分布式系统中都会存在这样的单点问题。具体地说,单点问题是指在一个分布式系统中,如果某一个组件出现故障就会引起整个系统的可用性大大下降甚至是处于瘫痪状态,那么我们就认为该组件存在单点问题。

ZooKeeper确实已经很好地解决了单点问题。根据前面章节对ZooKeeper技术内幕的讲解,我们已经可以了解到,基于“过半”设计原则,ZooKeeper在运行期间,集群中至少有过半的机器保存了最新的数据。因此,只要集群中超过半数的机器还能够正常工作整个集群就能够对外提供服务。

三、zookeeper容灾

解决了单点问题,是否就不需要考虑容灾了呢?答案是否定的,在搭建一个高可用的集群的时侯依然需要考虑容灾问题。正如上面讲到的,如果集群中超过半数的机器还在正常工作,集群就能够对外提供正常的服务。那么,如果整个机房出现灾难性的事故,这时显然已经不是单点问题的范畴了。

在进行 Zookeeper的容灾方案设计过程中,我们要充分考虑到“过半”原则。也就是说,无论发生什么情况,我们必须要保证Z0 Keeper集群中有超过半数的机器能够正常工作。因此,通常有以下两种部署方案。

1. 三机房部署

在进行容灾方案设计的时侯,我们通常是以机房为单位来考虑问题的。假如我们有三个机房可以部署服务,并且这三个机房间的网络情况良好,那么就可以在三个机房中都部署上若干个机器来组成一个ZooKeeper集群。

我们假定构成 ZooKeeper集群的机器总数为N,在三个机房中部署的ZooKeeper服务器数分别为N1、N2和N3,那么如果要使该Z00 Keeper集群具有容灾能力,我们可以根据如下算法来计算 Zoo Keeper集群的机器部署方案。

//向下取整,如果N为8,那么N1为3,如果N为7,那么N1也为3.
N1 = (N-1)/2  

//即如果N为8,那么N则为3,于是N2的取值范围就是1~2,分别是1和2.
//注意,1和2仅仅是N2的可选值,并非最终值一如果在N2为某个可选值的时候,无法计算出N的值,那么该可选值也无效。
1<= N2 <= (N-N1)/2

//在满足这个条件的基础下,遍历N2的可选值,得到N3。
N3 = N - N1 - N2 并且 N3 < N1 + N2

举例:
现在我们以7台机器为例,来看看如何分配三机房的机器分布。根据算法的步骤1,我们首先确定N1的取值为3.根据算法的步骤2,我们再确定了N2的可选值为1和2.最后在步骤3中,我们遍历N2的可选值,即可得到两种部署方案,分别是(3,1,3)和(3,2,2)。

2. 双机房部署

上面我们讲到了如何在三机房中部署Zookeeper集群来实现容灾。但是在实际情况中很多公司的机房规模无法达到三机房的条件,因此双机房部署成为了更为现实的方案。但是很遗憾的是,在目前版本(ZooKeeper官方给出的最新的稳定版本是3.4.6)的ZooKeeper中,还没有办法能够在双机房条件下实现较好的容灾效果一因为无论哪个机房发生异常情况,都有可能使得ZooKeeper集群中可用的机器无法超过半数。当然,在拥有两个机房的场景下,通常有一个机房是主要机房(一般而言,公司会花费更多的钱去租用一个稳定性更好、设备更可靠的机房,这个机房就是主要机房,而另一个机房的租用费相对而言则廉价一些)。我们唯一能做的,就是尽量在主要机房中部署更多的机器。例如,对于一个由7台机器组成的 Zoo Keeper集群,通常在主要机房中部署4台机器,剩下的3台机器部署到另一个机房中