同城双活的必修课 - 落地经验与关键挑战解析

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 同城双活作为一种容灾架构,通过在同一城市建立两个数据中心,以确保在一个数据中心发生故障时,系统能够快速切换到另一个数据中心,从而提高系统的可用性

1. 同城双活是什么

同城双活是一种容灾架构的设计模式,主要用于提高系统的可用性和容错性。它通常涉及在同一个城市内建立两个数据中心(机房),这两个数据中心同时对外提供服务,实现了高可用性和冗余。



关键特点和优势包括:

双活部署: 两个数据中心都处于活跃状态,同时处理用户请求。这样,当一个数据中心发生故障或维护时,另一个数据中心可以继续提供服务,确保业务的连续性。

故障隔离: 如果一个数据中心遇到故障,可以将流量切换到另一个正常工作的数据中心,减少服务中断时间。

负载均衡: 双活架构通常会利用 DNS 进行分流,让流量按照一定比例分布到两个数据中心,提高整体性能和吞吐量。

降低延迟: 由于两个数据中心都位于同一个城市,网络延迟相对较低,有助于提供更快的服务响应时间。

灾难恢复: 在同城双活的架构下,即使发生了灾难性事件,比如自然灾害,仍然有一个可用的数据中心,可以更迅速地进行灾难恢复。

 

需要注意的是,同城双活虽然提高了系统的可用性,但仍然存在无法解决的一些单点故障和问题,例如城市级别的停电或其他灾难性事件。在一些对服务连续性要求极高的场景中,可能需要考虑更复杂的容灾架构,如异地多活。

 

2. 什么样的业务需要同城双活

任何对高可用有要求的业务都可以在容灾架构上选择同城双活,同城双活是异地多活的基础。

3. 双活的部署范围

3.1 全量服务双活 or 部分服务双活

通常在同城双活架构中不是所有业务服务都必须进行双活部署,而是根据业务的特性和需求来进行选择,因为这涉及到成本和复杂性的权衡。有些业务服务可能并不是那么关键,或者其可用性要求并不高,在这种情况下,单活部署足够满足需求,同时减少了系统的复杂性和成本。

 

大多数公司会选择对一些关键业务中需要高可用性的服务,进行双活部署。而对非关键服务采取单活部署的方式,以平衡系统的可用性和成本。这样,即使一个数据中心发生故障不会导致关键业务不可用。



3.2 哪一部分双活?

1.挑选要双活的业务

首先需要确定哪一个业务双活,在一个互联网公司通常有好多个业务,例如阿里的淘宝、阿里云,字节的头条、抖音,滴滴的网约车,两轮车等等。建立双活首先确定好业务,然后找到业务中最核心的链路去建设双活(确定哪个业务搞双活通常和公司的战略息息相关)



2.确定业务的核心链路

在业务领域,核心链路可能表示业务流程中最关键、最重要的步骤或环节。这些环节是直接影响业务成功的关键步骤,比如滴滴网约车业务中核心链路有乘客发单,司机接单,完单等等



对核心业务的核心链路建设双活,保证在单机房故障时核心链路在另一个机房可以继续运转,保证核心链路不受影响既是保证了业务的成交量不受影响,那么整体的损失就相对较小。

 

在微服务盛行的时代,通常一条核心链路一定会包含多个服务,这其中会涉及到网关,业务服务,中台服务,中间件、存储等等



3.3 核心链路的服务如何梳理

通常一条核心链路中就包含了多个服务,那么具体包含哪些服务(业务 &存储等),这些服务又该如何梳理呢?通常的做法:首先需要人工梳理标记,最起码先标记处某一个链路的入口,例如乘客发单的入口是/create/order,然后结合全链路追踪能力观察从发单入口进来的流量( 生产流量,压测流量,测试流量)都经过哪些服务从而梳理出发单链路所涉及到的服务。

 

不过在一个大公司内,由于各种历史原因(懂的都懂)全链路追踪很有可能覆盖不全,那么就需要再结合日志以及监控等信息来弥补全链路追踪断链的情况,从而不断的完善与标记这条核心链路中所涉及到的服务,整个核心链路标记与维护的过程,大多数公司都是从最开始的人工到后期慢慢形成产品,自动化进行标记。



3.4 核心链路的问题

经过上面的梳理核心链路逐渐成型,但是问题也接踵而来。核心链路上的服务可能会越来越多,都要在双活架构中等量部署到新机房嘛?

 

答案:所谓的核心服务也并不一定要全量部署到新机房做双活,因为通过人工,全链路,日志,监控等手段标记的核心服务往往是大而全的,这里面标记出来的服务可能有很多,但是其中也有可能是弱依赖服务,弱依赖服务在同城双活部署场景下并不是必须的。

  • 强依赖服务:当一个服务是强依赖,意味着当这个服务出现故障不可用时,整个链路将会收到影响,甚至是整个系统的稳定性和可用性都会受到影响。
  • 弱依赖服务:当一个服务是弱依赖,意味着当这个服务出现故障不可用时,系统仍然可以部分或完全运行。弱依赖的设计有助于系统的弹性和容错性,因为系统的一部分可以在其他部分不可用的情况下继续运行。

 

如果是在小公司可能不用考虑这件事,但在具有一定规模的公司内,核心链路上的服务也许也会很多。如果全量部署成本依然会很高,特别是在提倡降本增效的近几年,双活的成本也是需要控制的。所以如果要做到成本可控,那么就需要找到核心链路中的强依赖服务部署在新机房做双活。



3.5 找到核心链路的最小集(强依赖)

如何识别核心链路中的强弱依赖?最简单的就是研发/运维人员手动筛选,但是随着系统变得复杂以及系统频繁的变更,弱依赖服务也有可能变成强依赖服务人工筛选成本太高而且准确性也难以得到保证。

 

如果你了解过混沌工程,也许会知道可以通过混沌工程主动模拟服务/接口故障,从而来梳理核心链路中服务的强弱依赖关系。梳理强弱依赖的好处 除了在双活加固场景下找到需要双活的最小链路集合,还可以针对强弱依赖做很多稳定性建设的事情,例如针对强依赖服务要建设限流能力,针对弱依赖服务要建设降级能力等等。这里涉及到的细节特别多,包括流量的来源,混沌工程平台的注入能力,核心链路的数据,可观测的能力,稳态的定义等等,在本文就不展开讲了,后面会单独写一篇文章介绍。



3.6 小结

在同城双活中,不是所有业务都需要双活,而是根据业务的关键性和可用性需求有选择地进行部署。核心链路的确定和梳理是双活实施的核心,找到核心链路中强依赖服务进行双活部署是成本最小,最理想化的双活部署范围。

4. 同城双活的其他关键因素

管控服务高可用

各种运维组件的管控层可用性往往会遭到忽视,但管控平台的高可用特别特别重要的。有很多真实发生的故障往往是因为管控层高可用能力建设不到位,导致出现故障后不能快速恢复。这里的细节特别多,举几个例子:

  • 假设是自动化切流,切流的平台在机房 A 单活或着对机房 A 的其他管控/存储有强依赖,那么当机房 A 故障时也无法完成切流动作,即使业务层和存储层的双活做的再好也没有任何用。
  • 假设故障时顺利切流(无论是自动/手动),当机房 B 承接了全部流量后,那监控、预案,限流,扩容等平台也不能在机房 A 单活或者对机房 A 的其他管控/存储有强依赖,因为当全部流量都切到机房 B 时,很有可能出现容量不足的情况,那么此时需要扩容/限流/降级等操作,如果这些操作依赖的管控平台不好用,可能会导致机房 B 也出现问题。

 

由于管控平台大多数是由不同的团队进行研发,每一个管控平台的架构可能都不同,管控平台保证高可用的方案也都不一样,不过通常有两种:双活或冷备,最终的目标只需要保证在故障时管控平台在另一个机房可用即可。建设的思路一般都是梳理强弱依赖,对强依赖改造为弱依赖,若改造不了,则需要对强依赖服务在单机房内完成闭环调用,不能跨机房调用。

 

存储服务高可用

在同城双活的场景下,两个机房间通过同城专线进行数据传输,延时相对较低。在这个背景下不同的存储服务有不同的方案,这里面挑两个最常见的组件简单介绍下,例如:

  • mysql

通常是主从模式部署,机房 A 部署主库,机房 B 部署从库,两个机房间存储会进行数据同步。这种场景下机房 B 的业务服务需要做改造将写请求路由到机房 1 的主库,将读请求路由到本机房的从库。(改造的方案可以利用中间件进行读写分离,例如 shardingsphere,一般大厂也都有自研的存储代理组件负责读写分离)



  • redis

业界通常的做法有主从架构、双写架构、双向同步架构

  • 主从架构:和 mysql 主从模式相同,机房 A 部署主库,机房 B 部署从库,使用原生主从复制保证数据一致性(类似于 codis 的设计思路)



  • 双写架构:双机房都部署 redis 主库和从库,业务流量在单机房完成读写请求闭环,由 proxy 完成对端机房异步写,不过这种方案有可能由于网络问题导致双机房 redis 数据不一致



  • 双向同步架构:双机房都部署 redis 主库和从库,业务流量单机房完成读写请求闭环,proxy 不需要进行异步写入对端机房,在 redis server 层进行双机房互相同步来保证数据一致性,需要解决数据冲突,要单独开发、成本较高(双向同步架构可以做为异地多活的基础能力)



5. 如何验证同城双活是否可用

当整体的同城双活工作都完成后,需要验证甚至是定期验证同城双活的能力是否可用,避免真出故障时才发现工作做的不够完善,也有可能因为架构的不断演进导致同城双活能力退化。那这里还是可以借助混沌工程思想,通过故障注入来对同城双活的能力进行演练验收。当模拟了单机房故障后,可以演练管控平台是否能正常进行切流,扩容,限流,降级等一系列操作,观察业务核心指标是否可以在双活机房迅速恢复,从而判断同城双活是否符合预期。

 

演练验证通常有两种做法:

  • 断专线:如果同城双活能力做的足够好,足够有信心,可以选择直接针对两个机房间的专线进行网络熔断(例如交换机上 down 端口),这种方式简单、粗暴、有效、可以较好的模拟单个机房故障。



  • 精细化故障注入:通常在一个机房内部署的服务不仅仅只有做了双活的业务,如果还有一些业务服务没有做双活,那么上面直接断专线演练肯定会影响这种单活的业务服务,所以需要按需去做精细化演练,例如对所有已经完成双活的业务服务注入网络故障,让其失联(无法访问其他服务/机房,也无法被其他服务访问,来模拟双活业务发生机房故障)



需要考虑如果用生产流量演练,可能会造成一定的损失,这里要看接入层的分流能力,接入层可以提前将大部分流量切换到单个机房,然后留一小部分流量在低峰期进行演练验证,降低损失。压测流量的话需要考虑压测流量的覆盖度以及仿真度,如果不够全面和真实那么对演练和验收的效果也都会打折扣。

6. 总结

同城双活作为一种容灾架构,通过在同一城市建立两个数据中心,以确保在一个数据中心发生故障时,系统能够快速切换到另一个数据中心,从而提高系统的可用性。在部署需要双活的服务时,首先要仔细评估业务的关键性和可用性需求,梳理业务的核心链路是双活的关键抓手,通过将核心链路中的强依赖服务作为重点部署对象,实现最小集的同城双活部署,降低双活成本。除了业务服务双活以外,管控和存储的高可用能力也是故障切换时的关键因素。

 

为了验证同城双活的可用性,可以利用混沌工程模拟单一数据中心的故障,进行演练关键操作,如切流、扩容、限流等,以确保系统能够在故障发生时迅速而可靠地恢复。这种方法有助于发现潜在的问题并提前制定有效的故障应对方案,确保业务连续性和稳定性。


作者介绍

张斌斌(Github 账号:binbin0325,公众号:柠檬汁 Code)Sentinel-Golang Committer 、ChaosBlade Committer 、 Nacos PMC 、Apache Dubbo-Go Committer。目前主要关注于混沌工程、中间件以及云原生方向。


相关文章
|
7月前
|
存储 分布式计算 大数据
HBase分布式数据库关键技术与实战:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入剖析了HBase的核心技术,包括数据模型、分布式架构、访问模式和一致性保证,并探讨了其实战应用,如大规模数据存储、实时数据分析及与Hadoop、Spark集成。同时,分享了面试经验,对比了HBase与其他数据库的差异,提出了应对挑战的解决方案,展望了HBase的未来趋势。通过Java API代码示例,帮助读者巩固理解。全面了解和掌握HBase,能为面试和实际工作中的大数据处理提供坚实基础。
471 3
|
7月前
|
SQL 分布式计算 监控
Sqoop数据迁移工具使用与优化技巧:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入解析Sqoop的使用、优化及面试策略。内容涵盖Sqoop基础,包括安装配置、命令行操作、与Hadoop生态集成和连接器配置。讨论数据迁移优化技巧,如数据切分、压缩编码、转换过滤及性能监控。此外,还涉及面试中对Sqoop与其他ETL工具的对比、实际项目挑战及未来发展趋势的讨论。通过代码示例展示了从MySQL到HDFS的数据迁移。本文旨在帮助读者在面试中展现Sqoop技术实力。
571 2
|
7月前
|
监控 负载均衡 Cloud Native
ZooKeeper分布式协调服务详解:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入剖析ZooKeeper分布式协调服务原理,涵盖核心概念如Server、Client、ZNode、ACL、Watcher,以及ZAB协议在一致性、会话管理、Leader选举中的作用。讨论ZooKeeper数据模型、操作、会话管理、集群部署与管理、性能调优和监控。同时,文章探讨了ZooKeeper在分布式锁、队列、服务注册与发现等场景的应用,并在面试方面分析了与其它服务的区别、实战挑战及解决方案。附带Java客户端实现分布式锁的代码示例,助力提升面试表现。
611 2
|
7月前
|
数据采集 消息中间件 监控
Flume数据采集系统设计与配置实战:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入探讨Apache Flume的数据采集系统设计,涵盖Flume Agent、Source、Channel、Sink的核心概念及其配置实战。通过实例展示了文件日志收集、网络数据接收、命令行实时数据捕获等场景。此外,还讨论了Flume与同类工具的对比、实际项目挑战及解决方案,以及未来发展趋势。提供配置示例帮助理解Flume在数据集成、日志收集中的应用,为面试准备提供扎实的理论与实践支持。
324 1
|
7月前
|
XML 分布式计算 监控
Oozie工作流管理系统设计与实践:面试经验与必备知识点解析
【4月更文挑战第9天】本文详述了Oozie工作流管理系统的核心概念,包括安装配置、Workflow XML、Action、Coordinator和Bundle XML定义。此外,讨论了工作流设计实践,如监控调试、自动化运维,并对比了Oozie与其他工作流工具的差异。文中还分享了面试经验及解决实际项目挑战的方法,同时展望了Oozie的未来发展趋势。通过学习,读者能提升Oozie技术能力,为面试做好充分准备。
154 0
|
7月前
|
SQL 存储 分布式计算
Hive数据仓库设计与优化策略:面试经验与必备知识点解析
本文深入探讨了Hive数据仓库设计原则(分区、分桶、存储格式选择)与优化策略(SQL优化、内置优化器、统计信息、配置参数调整),并分享了面试经验及常见问题,如Hive与RDBMS的区别、实际项目应用和与其他组件的集成。通过代码样例,帮助读者掌握Hive核心技术,为面试做好充分准备。
673 0
|
7月前
|
机器学习/深度学习 SQL 分布式计算
Spark核心原理与应用场景解析:面试经验与必备知识点解析
本文深入探讨Spark核心原理(RDD、DAG、内存计算、容错机制)和生态系统(Spark SQL、MLlib、Streaming),并分析其在大规模数据处理、机器学习及实时流处理中的应用。通过代码示例展示DataFrame操作,帮助读者准备面试,同时强调结合个人经验、行业趋势和技术发展以展现全面的技术实力。
690 0
|
7月前
|
消息中间件 监控 大数据
Kafka消息队列架构与应用场景探讨:面试经验与必备知识点解析
【4月更文挑战第9天】本文详尽探讨了Kafka的消息队列架构,包括Broker、Producer、Consumer、Topic和Partition等核心概念,以及消息生产和消费流程。此外,还介绍了Kafka在微服务、实时数据处理、数据管道和数据仓库等场景的应用。针对面试,文章解析了Kafka与传统消息队列的区别、实际项目挑战及解决方案,并展望了Kafka的未来发展趋势。附带Java Producer和Consumer的代码示例,帮助读者巩固技术理解,为面试做好准备。
759 0
|
6月前
|
人工智能 缓存 Java
技术经验解读:【转】详细解析用C#写的小游戏《彩色连珠》(附源代码)
技术经验解读:【转】详细解析用C#写的小游戏《彩色连珠》(附源代码)
31 0
|
7月前
|
Java
【类加载机制深度解析】,附带学习经验
【类加载机制深度解析】,附带学习经验

推荐镜像

更多