一个云原生双活架构方案
共 3431字,需浏览 7分钟
·
2021-08-28 14:39
互联网业务对于业务的连续性有非常高的要求,当业务发展到一定规模之后,容灾就是一个不得不面对的问题,如何实现一个RPO趋于0的同城双活架构是一个挑战。
四种容灾架构
容灾架构经历过四个发展阶段:
数据冷备:实现简单,业务无需改造;
在线热备:冷备只是做了数据备份,故障恢复的时候需要把服务热起来,恢复的时间会比较久,于是就有了在线热备方案,但热备常态下备份不提供在线服务,导致资源大量浪费,且可靠性难保证;
同城双活:较异地多活实现起来简单,业务改动较少,可以提供在线服务,让资源有效利用,故障恢复时间也比较短;
异地多活:多活实现起来比较复杂,需要做业务维度的set化,运维也比较复杂,优势是故障恢复时间短;
冷备VS热备
如下图,冷备只是把数据备份到IDC机房,故障时需要临时部署应用服务;热备方案相当于两个数据中心1:1的应用于环境,故障的时候可以切换到热备环境下。
但热备环境下常态下无流量,故障时切过去不能确定服务是否正常访问,考虑到成本,使用的较少。
同城双活
互联网应用使用较多的容灾方案是同城双活。应用服务双活,数据层单写、多读,故障恢复时间短,业务改造成本低,主备可用区常态承载流量,可用性高。
要求数据服务支持实时增量同步,接入层、应用层无状态,应用层可以接受跨区访问数据层增加的网络、数据延迟。
需要实现中间件层面的流量自动调度,以及数据层的故障HA自动切换,本可用区无跨区访问,或优先访问本区可用实例。
异地多活
异地多活一般是跨地域的多活方案,首先业务需要进行SET化改造,每个地域或数据中心可以同时接入写流量,用户请求与数据在某个数据单元内实现流量的闭环。
异地多活架构落地
我们看下一个用户请求进来之后在异地多活架构里面是怎么处理的。
用户请求先进入外网网关,我们会在用户请求中拼接目标数据中心地址,如果没有携带此类信息,就随机选择一个数据中心接入。如果用户请求包含了用户数据中心信息,则可以通过携带信息路由到目标数据中心了。
网关层有个处理脚本,如果网关是nginx可以通过lua脚本实现,将请求路由到用户所属set。
比如上海用户请求会被路由到上海数据中心,同时用户的数据与服务流程都在这个数据中心里面闭环掉,里面有完整的逻辑与数据。当上海地域发生故障时,可以从入口网关层面切流到北京,这也就要求北京数据中心有全量的上海数据,这样用户可以直接在北京数据中心内闭环完成自己的业务逻辑。
通过上面描述可以看出来,单元化架构实现的最大挑战是业务需要在单元内闭环处理,需要做数据同步或双向、多向同步。
云原生同城双活方案
做机房双活需要考虑投入资源、改造成本、运维成本,不同实现成本如下:
那云原生同城双活方案是什么样的呢?
接入层双活能力:
负载均衡LB,主备架构跨数据中心容灾
支持故障自动切换,保持VIP不变
应用层双活能力:
容灾服务TKE支持跨数据中心容灾
数据层双活能力:
数据库主备架构,故障后VIP不变
Kafka、ES、COS单集群可用区多副本
其他能力:
WAF、API网关、TDMQ、TDSQL等产品支持跨数据中心容灾
网络云原生支持就近访问
通过描述发现,其资源投入中等,部分数据层服务做了多活之后,成本零增加。
多数业务场景不需要业务做任何改造,零业务改造可以升级为同城双活的架构,运维成本低,所有数据层服务和接入层都通过云原生产品做故障自动切换,包括故障之后的数据及环境的自动恢复。
这种AZ级的故障为了保障判断的准确性,一般会在分钟级别完成故障的切换和恢复,恢复时间趋于零。
我们总结下,这套云原生多活产品,支持业务轻松实现同城双活,包括接入层、应用层、数据层,每层云原生产品都提供了对应双活的能力。
一个案例
以一个电商SaaS平台为例,介绍下云原生异地多活。
其业务全量部署在公有云单个可用区,一旦可用区故障服务中断,将影响数百万商家和上亿买家,所以希望实现单可用区故障不影响业务的连续性。
由于其业务资源众多,热备成本浪费严重,数据、服务改造成本大,跨可用区数据同步方案难度高。
那看下如何基于云原生同城双活方案进行改造,其特点包括:资源利用率高、业务零改造、数据可靠性高、运维成本低、故障恢复快。
故障注入测试,当一个可用区挂掉后,另一个可用区可以快速承接起来:
CLB容灾方案
当主可用区故障时,负载均衡可以在非常短时间内切换到可用区并恢复服务。这个过程无需人工操作,故障恢复时间短。
CLB的主备可用区是可用区级别的容灾,也就是说只有在整个可用区故障,如机房断点、机房出口光缆中断,才会切到备用可用区,而不是仅仅一个实例挂掉之后,就切换到备可用区。
数据库容灾方案
数据可以实现金融级别的一致性,比如备库加到三个可用区,数据在另一个数据中心有完整的一致性数据。故障之后MySQL的ip不需要变更,故障之后应用层ip不需要做任何配置变更,请求就近访问本可用区下的从库,提升访问性能。
数据的高可靠通过强同步方式实现,用户即使选择了只部署两个可用区,但后台还是会在三个可用区部署HA管控的系统。为避免出现两个可用区时发生网络分割导致脑裂问题,默认在第三可用区管控节点,真正故障的时候可以准确的把故障实例剔除掉,以实现金融级别的一致性可靠性。
Redis容灾方案
Redis一般用于缓存服务,对性能要求比较高,故障切换时,IP不变和MySQL一致。
在内核方面做了增强,在故障切换过程中,Redis主库可以优先切到本可用区从库,社区版本是不支持的。
Redis管控的HA节点在三个区可用,避免网络分区时脑裂的情况出现,保证切换时可以做正确的选主操作。
为提高访问效率,Redis支持就近接入特性,应用层应用去访问Redis是同区访问;跨可用区访问Redis是跨区访问;但跨区访问有网络延迟问题,跨区明显不如同区写入性能高。
MongoDB容灾方案
MongoDB故障之后IP不做变更,访问延迟也是就近访问本可用区的MongoDB的从副本。MongoDB默认部署三个可用区,就近接入,跨区之后,并发场景和跨区基本一致,就近接入之后访问吞吐也基本一致。
Kafka容灾方案
Kafka是同集群跨可用区多副本方案,切换之后访问的VIP保持不变,不需要业务做任何变更。原有Kafka的Topic的两个副本部署在一个分区,现在将其中一个副本放到另外一个分区,这样零成本。
从单个AZ到双AZ升级,后台管控是平行自动的,即使用户选择两个可用区,后台ZK还是部署三个可用区,这样保障在故障时选举出现脑裂问题。
ES容灾方案
ES也是同集群跨可用区多副本方案,切换后VIP保持不变,ES原来的两个副本,其中一个副本迁移到跨可用区内,可以保障ES在两个数据中心有完整的数据,保证整个数据故障时另一个数据中心还有容灾,且成本零增加。
ES切换依赖专用主节点,在三个区部署专用主节点,通过滚动模式自动升级到跨同城跨可用区架构。
对象存储容灾方案
原有容灾方案需要跨数据中心建两个,数据通过异步复制。这样数据会有RPO,没办法做到0,故障时候还需要自动切换,只有一半服务在提供服务,资源也会浪费。
对象存储在实现整个数据多AZ部署设计时,是进行分层设计的:
接入层(绿色部分)是无状态的,负责处理用户请求和路由。
数据存储模块(蓝色部分),包括用户写入数据和容灾副本。
用户请求到接入层后,把数据通过算法写入到不同的AZ里面,保证数据的完整性。当一个AZ故障之后,对象存储模块做简单的降级,不访问故障数据中心节点,就可实现整个故障的快速恢复。
DNS就近访问
为实现服务就近访问能力,需要基于HTTP做流量的智能调度,同可用区请求通过view优先访问同区IP服务,然后实现http就近访问。
如果用类似于dubbo服务治理框架,可以基于路由规则进行扩展,实现流量优先访问本可用区实例即可。
全链路容灾能力支持
一个容灾切换的过程,IP不变,当探测到主库不可用时,触发HA切换,通过网络管控更新VIP路由,把原有指向AZ1的实例指向AZ2,可以基于name service实现,需要定期对组件容灾能力进行验证,确保其可靠性。
总结
将以上各种高可用容灾组件组合起来可以实现灾备、同城双活、两地三中心甚至全球多活。