高可用的巅峰技术:跨机房部署、同城双活、异地多活究竟怎么玩儿?

2024-08-14 21:40:57 浏览数 (3)

大家好,我是冰河~~

在互联网大厂,有个普遍的现象:某种程度上,只要是比较重要的系统,都需要考虑系统的容灾问题。

通过实施容灾方案,将系统部署两套或者多套,并且这套系统或者多套系统可以部署到不同的机房,如果其中一套系统出现故障导致不可用,则可以迅速切换到另一套系统,提供7*24小时不间断服务。

一、容灾介绍

同城双活和异地多活都是典型的系统容灾部署方案,对于企业来说,尤其是大型互联网公司,比较重要的系统一般都会做容灾,采用同城双活,甚至异地多活的架构方案进行部署。

对于同城双活和异地多活来说,都是容灾的不同方案,它们对技术、部署成本、运维成本、网络带宽、网络稳定性等的要求都不一样。

多多少少都会增加部署的复杂度和部署成本,但是,容灾在某套系统出现故障时,能够迅速切换到另一套系统,保证系统的高可用。

二、宕机问题

企业的核心系统和比较重要的系统应该也必须考虑容灾问题,这里的容灾主要是通过部署两套或者多套系统实现,这两套或者多套系统一般是部署在不同的机房,避免只部署一套系统或者在同一机房部署多套系统出现宕机事故。

在实际场景中,哪怕我们部署了两套或者多套系统,但是这些系统是部署在同一个机房内,此时系统的可用性是受限于机房的可用性,如果机房出现网络不通或者其他事故,就会影响到系统的可用性,甚至造成系统长时间宕机。

这种系统事故不是人为造成的,但是如果不考虑容灾问题,或者容灾问题考虑不充分,将两套或者多套系统部署在同一个机房内就可能出现这种问题。

举个例子,如果已经考虑到容灾的问题,只是将两套或者多套系统部署在同一个机房中,如果这个机房的网络或者服务器出现了故障,机房发生了火灾,甚至机房所在的城市发生了地震、海啸、洪水等不可抗力的灾难时,哪怕部署在同一个机房内的多套系统之间实现的可用性再高,整个系统也是不可用的。

三、跨机房部署

跨机房部署,顾名思义就是将两套或者多套系统部署在多个机房,跨机房部署其实并没有想象中的那么简单和美好,实际上,将两套或者多套系统部署在多个机房是有一定的复杂度和挑战的。

以数据库为例,假设目前有两个机房,分别为机房A和机房B,数据库主库A和从库B都在A机房,那么B机房的应用如何读取到数据呢?此时,总体上有两种方案:跨机房读取数据和本机房内读取数据。

3.1 跨机房读取数据

如果是跨机房读取数据的话,B机房中的应用就会跨机房读取A机房的数据,如下图所示。

可以看到,此时B机房的应用会跨机房读取A机房的数据。

3.2 本机房内读取数据

如果是本机房内读取数据,则可以在B机房中部署一个从库,B机房中的从库跨机房同步A机房的数据,随后,B机房的应用读取本机房中从库的数据,如下图所示。

可以看到,在B机房中部署一个从库,跨机房同步A机房数据,B机房中的应用就可以读取本机房内从库的数据。

4.3 跨机房问题

无论是B机房内的应用跨机房读取数据,还是读取本机房内的数据,都会存在跨机房数据的传输问题,跨机房读取数据是B机房的应用直接读取A机房数据时,产生的跨机房传输数据问题。

而读取本机房内的数据,是数据库同步数据产生的跨机房传输数据问题。只要涉及到跨机房传输数据的问题,就会对机房之间的数据延迟有比较高的要求。

根据以往的经验来说,机房之间的数据延迟,与机房之间的物理距离有直接的关系,这里,给大家列举几个经验数据。

(1)同城双机房专线延迟

一般情况下,同城双机房专线延迟在1ms~3ms之间。

假设接口的响应时间要求控制在200ms之内,而一次接口调用可能会触发一些RPC服务或者其他服务,如果是同城双机房专线网络良好的情况下,跨机房调用服务,接口的响应时间可能会增加几毫秒,再有就是跨机房读写数据,接口响应时间增加几毫秒,都是可以接受的。

但是,如果跨机房调用服务,读写数据的次数比较多,来来回回耗费了几十、上百毫秒,此时就不能接受了。

(2)国内异地双机房专线延迟

一般情况下,就国内的异地双机房专线延迟在50ms之内。

具体还是要根据机房之前的物理距离来确定,比如北京到上海的专线延迟一般在30ms左右,而北京到广州的专线延迟在50ms左右,机房的物理距离不同,延迟也不尽相同。

在异地双机房专线的数据延迟影响下,如果要将接口的响应时间控制在200ms之内,就要避免频繁的跨机房调用服务和跨机房读写数据。

(3)国际异地双机房专线延迟

一般情况下,国际异地双机房专线的网络延迟会比国内异地双机房专线延迟高,一般会在100ms~200ms。

在这种场景下,就需要避免跨机房进行数据的同步处理,只考虑异步同步跨机房数据。

四、同城双活

同城双活方案是将系统部署在同一个城市的不同机房中,这种方案能够做到机房级别的容灾,而不能做到城市级别的容灾。

在同城双活方案中,同城的两个机房中,每个机房会承担一部分流量,涉及到服务的调用和数据读写时,尽量在本机房内完成,如果是RPC调用,不同机房的RPC服务可以向注册中心注册不同的服务分组,不同机房的RPC消费者只订阅本机房内的服务分组。

这样就可以实现RPC调用尽量发生在本机房内。如果是写数据,则可以向一个机房写数据,而实时同步到另一个机房,如下图所示。

可以看到,在实施同城双活方案时,主库可以部署在A机房中,A机房和B机房的数据都写到A机房的主库中,主库会将数据同步到A、B机房的从库。一旦A机房发生故障,可以将B机房的从库提升为主库,B机房继续对外提供服务。

在A机房和B机房同时部署了缓存,缓存中的数据可以由本机房内的从库进行同步,也可以由本机房的服务进行读写。

如果本机房的缓存中没有需要的数据,就到本机房的从库中进行查询,当然这里查询数据库的操作,要考虑缓存击穿、穿透和雪崩的问题。

当更新数据时,可以同时更新每个机房的数据。

不同机房的RPC服务可以向注册中心注册不同的服务分组,不同机房的RPC消费者只订阅本机房内的服务分组,这样就可以实现RPC调用尽量发生在本机房内。

五、异地多活

一般情况下,系统做同城双活容灾方案就够了,如果系统的业务发展到了淘宝级别,就需要考虑异地多活了。

如果是采用异地多活方案,机房之间的距离不宜太近,部署到同一个城市就不太合适了,所以,起码是要做跨城市级别的异地多活,甚至是跨国异地多活,在这种场景下,显然不能跨机房写数据了。

在异地多活场景下,数据同步可以采取主从同步 消息异步复制的方式来同步,也就是说,对于像MySQL、Redis这种数据,可以采用主从复制的方式,由一个机房同步到另一个机房。像缓存数据和一些NoSQL数据库的数据,可以使用消息异步复制的方式来同步数据,如下图所示。

可以看到,在异地多活场景下,对于像MySQL、Redis这种数据,可以采用主从复制的方式,由一个机房同步到另一个机房。像缓存数据和一些NoSQL数据库的数据,可以使用消息异步复制的方式来同步数据。

在异地多活场景下,还有一些要注意的问题:读取用户相关的数据时,尽量保证在同一个机房内处理,这时,就需要对用户的数据做分片处理,对同一个用户数据的读写操作,路由到同一个机房内。

对数据的读取和服务的调用,也尽量在同一个机房内完成。

另外,还有一种场景是在电商业务中,用户相关的数据,例如用户查询自己的订单数据时,用户自己的订单数据与用户数据在同一个机房内,但是订单数据中的店铺数据和商家的一些基本信息,可能就存储在另外的机房了。

此时,对于服务的调用和数据的读取,优先保证在本机房内进行,如果不得已发生跨机房读取数据的操作,有一定的延迟,也可以接受。

还有一点需要说明的是:如果同城双活架构方案能够满足需求,就不要轻易尝试异地多活架构,实际上,异地多活架构过于复杂,很少有公司能够搭建出真正的异地多活架构。

六、总结

本文大部分内容节选自冰河的《Seckill秒杀系统》专栏,在《Seckill秒杀系统》专栏中,不仅仅是带着大家从零开始写一个秒杀业务系统,而是从需求立项到架构设计、环境搭建到编码实现、问题重现到代码优化、单体应用架构到微服务架构、秒杀系统极致优化到高并发方案落地、流量治理到链路追踪、防刷方案到风控设计、集群部署到全链路压测,再对秒杀系统整体进行极致优化。

Seckill秒杀系统整体专栏内容如下。

七、写在最后

在冰河的知识星球除了目前正在热更的高性能网关外,还有其他6个项目,像分布式IM即时通讯系统、Sekill分布式秒杀系统、手写RPC、简易商城系统等等,这些项目的需求、方案、架构、落地等均来自互联网真实业务场景,让你真正学到互联网大厂的业务与技术落地方案,并将其有效转化为自己的知识储备。

0 人点赞