[分布式]异地多活架构

2024-02-11 19:48
文章标签 架构 分布式 异地 多活

本文主要是介绍[分布式]异地多活架构,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

异地指地理位置上的不同,多活指不同地理位置上的系统都能够提供业务服务。

 

判断标准:

  1. 正常情况下,用户无论访问哪一个地点的业务系统,都能够得到正确的业务服务。

  2. 某地异常时,用户访问其他地方正常的业务系统,能够得到正确的业务服务。

异地多活的代价:

  1. 系统复杂度会有质的变化。

  2. 成本大大增加。

架构模式

1. 同城异区

部署在同一个城市不同区的机房,用专用网络连接。

同城异区两个机房距离一般就是几十千米,网络传输速度几乎和同一个机房相同,降低了系统复杂度、成本。

这个模式无法解决极端的灾难情况,例如某个城市的地震、水灾,此方式是用来解决一些常规故障的,例如机房的火灾、停电、空调故障。

2. 跨城异地

部署在不同城市的多个机房,距离要远一些,例如北京和广州。

此模式就是用来处理极端灾难情况的,例如城市的地震、相邻城市的大停电。

跨城异地主要问题就是网络传输延迟,例如北京到广州,正常情况下的RTT(Round-Trip Time 往返时延)是50毫秒,当遇到网络波动等情况,会升到500毫秒甚至1秒,而且会有丢包问题。

物理距离必然导致数据不一致,这就得从“数据”特性来解决,如果是强一致性要求的数据(如存款余额),就无法做异地多活。

举例,存款余额支持跨城异地多活,部署在北京和广州,当光缆被挖断后,会发生:

  • 用户A余额有10000,北京和广州是一致的。

  • A在广州机房给B转5000,广州余额为5000,由于网络不通,北京此时的余额为10000。

  • A在北京发现余额还是10000,给C转10000,由于网络不通,广州的余额为5000。

  • A在广州又可以给D转5000。

这就出事儿了,所以这类数据不会做跨城异地多活,只能用同城异区架构,因为同城的网络环境要好很多,可以搭建多条互联通道,成本也不会太高。

跨城异地模式适用于对数据一致性要求不高的场景,例如:

  1. 用户登录,数据不一致时重新登录即可。

  2. 新闻网站,一天内新闻数据变化较少。

  3. 微博网站,即使丢失一点微博或评论数据也影响不大。

3. 跨国异地

部署在不同国家的多个机房。

此模式的延时就更长了,正常情况也得几秒,无法满足正常的业务访问。

所以,跨国异地多活适用于:

  • 为不同地区用户提供服务

例如,亚马逊美国是为美国用户服务的,亚马逊中国的账号是无法登录美国亚马逊的。

  • 只读类业务

例如谷歌的搜索,不管用户在哪个国家搜索,得到的结果基本相同,对用户来说,跨国异地的几秒延迟,对搜索结果没什么影响。

跨城异地多活设计技巧

1. 保证核心业务的异地多活

思维误区:要保证所有业务都能异地多活。

假设用户子系统,负责注册、登录、用户信息这3个业务,由于有海量用户,所以对用户进行分区,分配到不同数据中心,正常情况下某个用户属于某个主分区,并在其他分区也有备份,通过hash计算得出属于哪个中心。

如果想要保证注册业务多活,可能会有问题,例如,A中心注册了用户,数据还未同步到B中心时A宕了,为了支持多活,需要可以让用户到B中心重新注册,但一个手机号只能注册一个账号,A恢复后就有冲突了。

如果要保证用户信息业务多活,也会有问题,例如,A、B两个中心在异常情况下都修改了用户信息,如何处理冲突?

可以发现,注册、登录、用户信息这3个业务都支持多活的话,是非常难的,有的问题甚至是无解的。解决的方法就是:优先实现核心业务的异地多活

这个示例中,“登录”才是核心业务,例如系统的日活是1000万,每天的注册可能是几万,修改用户信息的可能还不到1万,但登录是1000万,很明显要保证登录的异地多活。

2. 保证核心数据最终一致性

思维误区:要保证所有数据实时同步。

由于物理上的限制,所有数据都实时同步,是一个无法达到的目标。

必须要尽量减少数据同步,只同步核心业务相关的数据。

例如上面的例子,登录产生的token或session信息,数据量很大,实际上不需要同步到其他中心,即使丢失了重新登录就可以了,会影响用户体验,但是可以接受的。

3. 采用多种手段同步数据

思维误区:只使用存储系统的同步功能。

存储系统本身就有强大的同步功能,例如 mysql redis 都可以很好的实现同步,但某些场景下是无法满足需要的,所以要使用多种手段配合,例如:

  • 消息队列

创建账号后,将账号数据通过消息队列同步到其他业务中心。

  • 二次读取

例如用户在A中心注册了,然后访问了B中心,此时B还没有拿到账号数据,为了解决这个问题,B中心在读取本地数据失败时,可以根据路由规则,再去A中心访问一次。

  • 回源读取

例如session数据没有同步,用户在A中心登录,B中心可以拿着 session id 到A中心请求session数据。

4. 只保证绝大部分用户的异地多活

思维误区:要保证业务 100% 可用。

物理规律决定了异地多活无法保证100%的业务可用。

以转账业务为例,在北京和上海两个中心实现了实时转账的异地多活,在异常情况下会出现问题,例如用户有一万存款,在北京给人转了一万,又到上海给人转了一万。

所以,无法做到实时转账的异地多活,需要通过特殊业务受到实现。

例如,除了“实时转账”外,还提供“转账申请”业务,用户在上海提交了转账请求,并不立即转账,而是后台异步处理,如果发现北京中心不可用,就等待重试,北京恢复后,如果发现余额不足就转账失败。

这个方式牺牲了一些用户体验,本来一次完成的操作变为了2次,一次提交转账申请,另一次是确认转账结果。

对于用户体验,可以采取一些补偿措施,例如:

  • 公告

例如由于xxx原因导致您的不便,技术哥哥正在紧急处理等等。

  • 事后补偿

例如送代金券、小礼品等。

  • 补充体验

例如上面的转账例子,可以在转账结果出来后给用户发个短信,减少用户不时的登录查看。

小结

这篇关于[分布式]异地多活架构的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/700662

相关文章

Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)

《Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)》本文主要介绍了Golang分布式锁实现,采用Redis+Lua脚本确保原子性,持可重入和自动续期,用于防止超卖及重复下单,具有一定... 目录1 概念应用场景分布式锁必备特性2 思路分析宕机与过期防止误删keyLua保证原子性可重入锁自动

基于MongoDB实现文件的分布式存储

《基于MongoDB实现文件的分布式存储》分布式文件存储的方案有很多,今天分享一个基于mongodb数据库来实现文件的存储,mongodb支持分布式部署,以此来实现文件的分布式存储,需要的朋友可以参考... 目录一、引言二、GridFS 原理剖析三、Spring Boot 集成 GridFS3.1 添加依赖

Maven 插件配置分层架构深度解析

《Maven插件配置分层架构深度解析》:本文主要介绍Maven插件配置分层架构深度解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Maven 插件配置分层架构深度解析引言:当构建逻辑遇上复杂配置第一章 Maven插件配置的三重境界1.1 插件配置的拓扑

Redis实现分布式锁全解析之从原理到实践过程

《Redis实现分布式锁全解析之从原理到实践过程》:本文主要介绍Redis实现分布式锁全解析之从原理到实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景介绍二、解决方案(一)使用 SETNX 命令(二)设置锁的过期时间(三)解决锁的误删问题(四)Re

Gradle下如何搭建SpringCloud分布式环境

《Gradle下如何搭建SpringCloud分布式环境》:本文主要介绍Gradle下如何搭建SpringCloud分布式环境问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Gradle下搭建SpringCloud分布式环境1.idea配置好gradle2.创建一个空的gr

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

深入理解Apache Kafka(分布式流处理平台)

《深入理解ApacheKafka(分布式流处理平台)》ApacheKafka作为现代分布式系统中的核心中间件,为构建高吞吐量、低延迟的数据管道提供了强大支持,本文将深入探讨Kafka的核心概念、架构... 目录引言一、Apache Kafka概述1.1 什么是Kafka?1.2 Kafka的核心概念二、Ka

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Java异常架构Exception(异常)详解

《Java异常架构Exception(异常)详解》:本文主要介绍Java异常架构Exception(异常),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. Exception 类的概述Exception的分类2. 受检异常(Checked Exception)

redis+lua实现分布式限流的示例

《redis+lua实现分布式限流的示例》本文主要介绍了redis+lua实现分布式限流的示例,可以实现复杂的限流逻辑,如滑动窗口限流,并且避免了多步操作导致的并发问题,具有一定的参考价值,感兴趣的可... 目录为什么使用Redis+Lua实现分布式限流使用ZSET也可以实现限流,为什么选择lua的方式实现