急性肠炎症状

首页 » 常识 » 预防 » 干货搞懂异地多活,看这篇就够了
TUhjnbcbe - 2023/6/22 21:19:00

阅读本文大约需要20分钟,请提前加入浮窗。

在软件开发领域,「异地多活」是分布式系统架构设计的一座高峰,很多人经常听过它,但很少人理解其中的原理。

异地多活到底是什么?为什么需要异地多活?它到底解决了什么问题?究竟是怎么解决的?

这些疑问,想必是每个程序看到异地多活这个名词时,都想要搞明白的问题。

有幸,我曾经深度参与过一个中等互联网公司,建设异地多活系统的设计与实施过程。所以今天,我就来和你聊一聊异地多活背后的的实现原理。

认真读完这篇文章,我相信你会对异地多活架构,有更加深刻的理解。

这篇文章干货很多,希望你可以耐心读完。

01系统可用性

要想理解异地多活,我们需要从架构设计的原则说起。

现如今,我们开发一个软件系统,对其要求越来越高,如果你了解一些「架构设计」的要求,就知道一个好的软件架构应该遵循以下3个原则:

高性能高可用易扩展

其中,高性能意味着系统拥有更大流量的处理能力,更低的响应延迟。例如1秒可处理10W并发请求,接口响应时间5ms等等。

易扩展表示系统在迭代新功能时,能以最小的代价去扩展,系统遇到流量压力时,可以在不改动代码的前提下,去扩容系统。

而「高可用」这个概念,看起来很抽象,怎么理解它呢?通常用2个指标来衡量:

平均故障间隔MTBF(MeanTimeBetweenFailure):表示两次故障的间隔时间,也就是系统「正常运行」的平均时间,这个时间越长,说明系统稳定性越高故障恢复时间MTTR(MeanTimeToRepair):表示系统发生故障后「恢复的时间」,这个值越小,故障对用户的影响越小

可用性与这两者的关系:

可用性(Availability)=MTBF/(MTBF+MTTR)*%

这个公式得出的结果是一个「比例」,通常我们会用「N个9」来描述一个系统的可用性。

从这张图你可以看到,要想达到4个9以上的可用性,平均每天故障时间必须控制在10秒以内。

也就是说,只有故障的时间「越短」,整个系统的可用性才会越高,每提升1个9,都会对系统提出更高的要求。

我们都知道,系统发生故障其实是不可避免的,尤其是规模越大的系统,发生问题的概率也越大。这些故障一般体现在3个方面:

硬件故障:CPU、内存、磁盘、网卡、交换机、路由器软件问题:代码Bug、版本迭代不可抗力:地震、水灾、火灾、战争

这些风险随时都有可能发生。所以,在面对故障时,我们的系统能否以「最快」的速度恢复,就成为了可用性的关键。

可如何做到快速恢复呢?

这篇文章要讲的「异地多活」架构,就是为了解决这个问题,而提出的高效解决方案。

下面,我会从一个最简单的系统出发,带你一步步演化出一个支持「异地多活」的系统架构。

在这个过程中,你会看到一个系统会遇到哪些可用性问题,以及为什么架构要这样演进,从而理解异地多活架构的意义。

02单机架构

我们从最简单的开始讲起。

假设你的业务处于起步阶段,体量非常小,那你的架构是这样的:

这个架构模型非常简单,客户端请求进来,业务应用读写数据库,返回结果,非常好理解。

但需要注意的是,这里的数据库是「单机」部署的,所以它有一个致命的缺点:一旦遭遇意外,例如磁盘损坏、操作系统异常、误删数据,那这意味着所有数据就全部「丢失」了,这个损失是巨大的。

如何避免这个问题呢?我们很容易想到一个方案:备份。

你可以对数据做备份,把数据库文件「定期」cp到另一台机器上,这样,即使原机器丢失数据,你依旧可以通过备份把数据「恢复」回来,以此保证数据安全。

这个方案实施起来虽然比较简单,但存在2个问题:

恢复需要时间:业务需先停机,再恢复数据,停机时间取决于恢复的速度,恢复期间服务「不可用」数据不完整:因为是定期备份,数据肯定不是「最新」的,数据完整程度取决于备份的周期

很明显,你的数据库越大,意味故障恢复时间越久。那按照前面我们提到的「高可用」标准,这个方案可能连1个9都达不到,远远无法满足我们对可用性的要求。

那有什么更好的方案,既可以快速恢复业务?还能尽可能保证数据完整性呢?

这时你可以采用这个方案:主从副本。

03主从副本

你可以在另一台机器上,再部署一个数据库实例,让这个新实例成为原实例的「副本」,让两者保持「实时同步」,就像这样:

我们一般把原实例叫作主库(master),新实例叫作从库(slave)。这个方案的优点在于:

数据完整性高:主从副本实时同步,数据「差异」很小抗故障能力提升:主库有任何异常,从库可随时「切换」为主库,继续提供服务读性能提升:业务应用可直接读从库,分担主库「压力」读压力

这个方案不错,不仅大大提高了数据库的可用性,还提升了系统的读性能。

同样的思路,你的「业务应用」也可以在其它机器部署一份,避免单点。因为业务应用通常是「无状态」的(不像数据库那样存储数据),所以直接部署即可,非常简单。

因为业务应用部署了多个,所以你现在还需要部署一个「接入层」,来做请求的「负载均衡」(一般会使用nginx或LVS),这样当一台机器宕机后,另一台机器也可以「接管」所有流量,持续提供服务。

从这个方案你可以看出,提升可用性的关键思路就是:冗余。

没错,担心一个实例故障,那就部署多个实例,担心一个机器宕机,那就部署多台机器。

到这里,你的架构基本已演变成主流方案了,之后开发新的业务应用,都可以按照这种模式去部署。

但这种方案还有什么风险吗?

04风险不可控

现在让我们把视角下放,把焦点放到具体的「部署细节」上来。

按照前面的分析,为了避免单点故障,你的应用虽然部署了多台机器,但这些机器的分布情况,我们并没有去深究。

而一个机房有很多服务器,这些服务器通常会分布在一个个「机柜」上,如果你使用的这些机器,刚好在一个机柜,还是存在风险。

如果恰好连接这个机柜的交换机/路由器发生故障,那么你的应用依旧有「不可用」的风险。

虽然交换机/路由器也做了路线冗余,但不能保证一定不出问题。

部署在一个机柜有风险,那把这些机器打散,分散到不同机柜上,是不是就没问题了?

这样确实会大大降低出问题的概率。但我们依旧不能掉以轻心,因为无论怎么分散,它们总归还是在一个相同的环境下:机房。

那继续追问,机房会不会发生故障呢?

一般来讲,建设一个机房的要求其实是很高的,地理位置、温湿度控制、备用电源等等,机房厂商会在各方面做好防护。但即使这样,我们每隔一段时间还会看到这样的新闻:

年5月27日,杭州市某地光纤被挖断,近3亿用户长达5小时无法访问支付宝年7月13日,B站部分服务器机房发生故障,造成整站持续3个小时无法访问年10月9日,富途证券服务器机房发生电力闪断故障,造成用户2个小时无法登陆、交易...

可见,即使机房级别的防护已经做得足够好,但只要有「概率」出问题,那现实情况就有可能发生。虽然概率很小,但一旦真的发生,影响之大可见一斑。

看到这里你可能会想,机房出现问题的概率也太小了吧,工作了这么多年,也没让我碰上一次,有必要考虑得这么复杂吗?

但你有没有思考这样一个问题:不同体量的系统,它们各自

1
查看完整版本: 干货搞懂异地多活,看这篇就够了