百亿级流量的系统架构该怎么设计,今天就来教会你!

news2024/11/19 16:43:59
V-xin:ruyuan0330 获得600+页原创精品文章汇总PDF

目录

  • 一、前情提示
  • 二、清晰划分系统边界
  • 三、引入消息中间件解耦
  • 四、利用消息中间件削峰填谷
  • 五、手动流量开关配合数据库运维
  • 六、支持多系统同时订阅数据
  • 七、系统解耦后的感受
  • 八、下集预告

一、前情提示

上一篇文章《第一次当架构师,我设计高并发架构发现了N个痛点。。。》,给大家初步讲述了一套大规模复杂系统中,两个核心子系统之间一旦耦合,会发生哪些令人崩溃的场景。如果还没看上篇文章的,建议先看一下。

这篇文章,咱们就给大家来说一说通过MQ消息中间件的使用,如何重构系统之间的耦合,让系统具备高度的可扩展性。

首先来回看一下之前画的一张两个系统之间进行耦合的一个大图,从这个图里我们可以看到两个系统完全通过一套共享存储(数据库集群+缓存集群)进行了耦合。

在这里插入图片描述

二、清晰的划分系统边界

只要有耦合,一旦要解决耦合,那么第一个要干的事儿就是先划分清楚系统之间的边界。

比如上面那两套系统都共享了一套存储集群,那么大家可以先思考一下,两个系统之间的边界应该如何划分?也就是说,中间那套缓存集群和数据库集群,到底应该是属于哪个系统?

首先我们看一下,缓存集群和数据库集群主要是给谁用的?

很明显就是给数据查询平台用的,说白了,那两套集群都是数据查询平台赖以生存的核心底层数据存储,这里存储的数据也都是属于数据查询平台的核心数据。

对于实时计算平台来说,他只不过是将自己计算后的结果写入到缓存集群和数据库集群罢了。

实时计算平台只要写入过后,后续就不会再管那些数据了,所以这两套集群明显是不属于实时计算平台的。

好,那么系统之间的边界就很清晰的划分清楚了,大家看一下如下的图。首先从系统整体架构的架构而言,两套系统之间的关系应该是下面这样子的。

在这里插入图片描述

三、引入消息中间件解耦

只要划分清楚了系统之间的边界,接着下一步,就是引入消息中间件来进行解耦了。

如果大家对消息中间件的使用场景还不太熟悉的,可以参考之前的一篇文章:《做了几年开发,你知道自己的系统为什么要用消息中间件吗?》这篇文章里面,对消息中间件的各种使用场景都有说明。

我们只要引入一个消息中间件,然后让实时计算平台将计算好的数据按照预设的格式直接写入到消息中间件即可。

同时,数据查询平台需要增加一个数据接入服务,这个数据接入服务就是负责将消息中间件里的数据消费出来,然后落地写入到本地的缓存集群和数据库集群。

在这里插入图片描述

如上图所示,此时两个系统之间已经不再直接基于共享数据存储进行耦合了,中间加入了MQ消息中间件。

这个消息中间件仅仅就是用于两个系统之间的数据交互和传输,职责简单,清晰明了。

这样做最大的好处,就是数据查询平台自身可以对涌入自身平台的数据按照自己的需求进行定制化的管控了,不会像之前那样的被动。

实际上在上述架构之下,涌入数据查询平台的所有数据,都需要经过数据接入服务那一关。在数据接入服务那里就可以随意根据自己的情况进行管理。


四、利用消息中间件削峰填谷

还记得上一篇文章我们提到,这两个系统之间第一个大痛点,就是实时计算平台会高并发写入数据查询平台,之前不做任何管控的时候,导致各种意外发生。

举个例子,比如快速增长的写库压力导致数据查询平台必须优先cover住分库分表那块的架构,打破自己的架构演进节奏;

比如突然意外出现的热数据因为不做任何写入管控,一下子差点把数据库服务器击垮。

因此一旦用消息中间件在中间挡了一层之后,我们就可以进行削峰填谷了。

那什么叫做削峰填谷呢?其实很简单,我们先来看看,如果不做任何管控,实时计算平台写入数据库集群的写并发曲线图,大概如下面所示。

在高峰期,写入会有一个陡然上升的尖峰。

在这里插入图片描述

就好比说,平时每秒写入并发就500,但是高峰期写入并发请求有5000,那么大家就会看到上面的那张图,在高峰期突然冒出来一个尖峰,一下子涌入并发5000请求,此时数据查询平台的数据库集群可能就会受不了。


但是,如果我们在数据接入服务里做一个限流控制呢?

也就是说,在数据接入服务里,根据当前数据查询平台的数据库集群能承载的并发上限,比如说就是最多承载每秒3000。

好!那么数据接入服务自己就控制好,每秒最多就往自己本地的数据库集群里写入最多每秒3000的请求压力。

此时就会出现削峰填谷的效果,大家看下面的图。

在这里插入图片描述

因为在高峰期瞬时写入压力最大有5000/s,但是数据接入服务做了流量控制,最多就往本地数据库集群写入3000/s,那么每秒就会有2000条数据在消息中间件里做一个积压。

但是积压一会儿不要紧,最起码保证说在高峰期,这个向上的尖峰被削平了,这就是所谓的削峰。

然后在高峰期过了之后,本来每秒可能就100/s的写入压力,但是此时数据接入服务会持续不断的从消息中间件里取出来数据然后持续以最大3000/s的写入压力往本地数据库集群里写入。

那么在低峰期,大家看到还会持续一段时间是3000/s的写入速度往本地数据库里写。

原来的图里在低峰期是谷底,现在谷底被填平了,这就是所谓的填谷。


通过这套削峰填谷的机制,就可以保证数据查询平台完全能够以自己接受的了的速率,均匀的把MQ里的数据拿出来写入自己本地数据库集群中。

这样子无论实时计算平台多高的并发请求压力过来,哪怕是那种异常的热数据,瞬间上万并发请求过来也无所谓了。

因为MQ中间件可以抗住瞬间高并发写入,但是数据查询平台永远都是稳定匀速的写入自己本地数据库。

这样的话,数据查询平台就不需要去过多的care实时计算平台带给自己的压力了,可以按照自己的节奏规划好整体架构的演进策略,按照自己的脚本去迭代架构。

说了那么多,老规矩!给大家来一张图,此时的架构图如下所示。

大伙儿可以直观的感受一下,在数据接入服务中多了一个限流的模块。

在这里插入图片描述

五、手动流量开关配合数据库运维操作

现在基于消息中间件将两个系统隔离开来之后,另外一个大的好处就是:数据查询平台做任何数据运维的操作,比如说DDL、分库分表扩容、数据迁移,等等诸如此类的操作,已经跟实时计算平台彻底无关了。

实时计算平台主要就是简单的往消息中间件写入,其他的就不用管了。

然后如果数据查询平台要做一些数据库运维的操作,此时就可以通过在数据接入服务中加入一个手动流量开关,临时将流量开关关闭一会儿。

比如选择一个下午大家都在工作或者午睡的时候,相对低峰的时期,半小时内关闭流量开关。

然后此时数据接入服务就不会继续往本地数据库写入数据了,此时写入操作就会停止,然后就在半小时内迅速完成数据库运维操作。

等相关操作完成之后,再次打开流量开关,继续从MQ里消费数据再快速写入到本地数据库内即可。

这样,就可以完全避免了同时写入数据,还同时进行数据库运维操作的窘境。否则在早期耦合的状态下,每次进行数据库运维操作,还得实时计算平台团队的同学配合一起进行各种复杂操作,才能避免线上出现故障,现在完全不需要人家的参与了,自己团队就可以搞定。

整个过程,我们还是用一张图,给大家呈现一下:

在这里插入图片描述

六、支持多系统同时订阅数据

引入消息中间件之后,还有另外一个好处,就是其他的一些系统也可以按照自己的需要去MQ里订阅实时计算平台计算好的数据。

举个例子,在这套平台里,还有数据质量监控系统,需要获取计算数据进行数据结果准确性和质量的监控。

另外,还有数据链路监控系统,同样需要将MQ里的数据作为数据计算链路中的一个核心点数据采集过来,进行数据全链路的监控和自动追踪。

如果没有引入MQ消息中间件概念的话,那么是不是就会导致实时计算平台除了将数据写入一份到数据库集群,还需要通过接口发送给数据质量监控系统?还需要发送给数据链路监控系统?这样简直是坑爹到不行,N个系统全部耦合在一起。

之前的文章《做了几年开发,你知道自己的系统为什么要用消息中间件吗?》就阐述了这种多系统订阅同一份数据,但是通过接口调用耦合在一起的窘境。

这样每次要是有一点变动,各个系统的负责人都在一起开会商讨,修改代码,修改接口,考虑各种调用细节,等等。

但是现在有了消息中间件,完全可以通过MQ支持的“Pub/Sub”消息订阅模型,不同的系统都可以来订阅同一份数据,大家自己按需消费,按需处理,各个系统之间完全解耦。

整个系统的可扩展性瞬间提升了很多,因为各个系统各自迭代和演进架构,都不需要强依赖其他的系统了。

在这里插入图片描述

七、系统解耦后的感受

云开雾散!各个团队的同学终于不用天天扯皮,今天说你的系统影响了我,明天是我的系统影响了你。

同时也压根儿不用去关注其他的系统,只要有一个总架构师把控好整体架构,各个team都按照这个分工协作来做即可。

消息中间件的引入,消除了系统的耦合性,大幅度提升了系统的可扩展性,各个team都可以快速的独立的迭代扩展自己的架构和系统。

PS:最重要的,不同team的同学,再也不用为了一些鸡毛蒜皮的事儿加班到深更半夜,导致他们的女朋友觉得他们要在一起了。。。


八、下集预告

下一篇文章,是关于可扩展架构的最后一篇。我们把整体架构梳理完毕了之后,就可以来看一看具体到MQ消息中间件的层面,他是怎么通过“Pub/Sub”的订阅模型,让一份数据发布出去,然后让多个不同的系统来订阅同一份数据的。

V-xin:ruyuan0330 获得600+页原创精品文章汇总PDF

另外推荐儒猿课堂的1元系列课程给您,欢迎加入一起学习~

互联网Java工程师面试突击课(1元专享)

SpringCloudAlibaba零基础入门到项目实战(1元专享)

亿级流量下的电商详情页系统实战项目(1元专享)

Kafka消息中间件内核源码精讲(1元专享)

12个实战案例带你玩转Java并发编程(1元专享)

Elasticsearch零基础入门到精通(1元专享)

基于Java手写分布式中间件系统实战(1元专享)

基于ShardingSphere的分库分表实战课(1元专享)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/106790.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

吊炸天的云原生,到底是个啥

云原生技术里有很多技术、概念和术语,不了解的人,往往弄不清楚而一头雾水,这些概念都是啥,之间是什么关系?本文要说的就是这些。本文更多是科普和扫盲,无意面面俱到,也无意深入细节。 本文适合一…

Allegro如何合并同名网络铜皮操作指导

Allegro如何合并同名网络铜皮操作指导 Allegro可以将同名网络的铜皮合并起来,如下图,需要把下面两块铜皮合并成一块铜皮 具体操作如下 选择Shape选择merge shapes

剑指Offer-面试题1:整数除法——你真的会用Math.abs吗?

整数除法 题目要求 输入2个int型整数,它们进行除法计算并返回商,要求不得使用乘号*、除号/及求余符号%。当发生溢出时,返回最大的整数值。假设除数不为0。例如,输入15和2,输出15/2的结果,即7。 有问题的…

使用OpenCV的函数polylines()绘制多条相连的线段和多边形;使用函数fillPoly()绘制带填充效果的多边形

函数polylines()可用来根据点集绘制多条相连的线段,也可用来绘制多边形。 函数polylines()有两种原型,这里只向大家介绍比较常用的那种原型。 函数polylines()的C原型如下: void cv::polylines(InputOutputArray img,const Point *const *…

Power BI 11个必学官方示例数据案例(附下载链接)

在开始学习Power BI时,最大的问题就是不知道哪里找数据,或者有数据却对搭建看板毫无头绪, 不知道该从哪里下手。 本文收集整理了官网上最值得学习的11个案例,包括不同行业和分析方法,方便大家按需学习。点击标题即可转…

安徽省建设工程监理人员从业水平能力证书

安徽省建设监理协会会员单位从业人员是指已通过安徽省建设监理协会组织的从业水平能力认定考试,取得《安徽省建设工程监理人员从业水平能力证书》,并在工程建设中从事监理工作的监理工程师和监理员(以下简称“监理工程师、监理员”&#xff0…

LLVM中矩阵Matrix的实现分析

1 背景说明 Clang提供了C/C语言对矩阵的扩展支持,以方便用户使用可变大小的二维数据类型来实现计算,目前该特性还是实验版,设计和实现都在变化中。LLVM目前设计为支持小型列矩阵(column major),其对矩阵的…

Java字节码介绍

Java字节码 概述 学习 Java 的都知道,我们所编写的 .java 代码文件通过编译将会生成 .class 文件,最初的方式就是通过 JDK 的 javac 指令来编译,再通过 java 命令执行 main 方法所在的类,从而执行我们的 Java 程序。而在这中间所…

【矩阵论】6. 矩阵理论——算子范数

6.2 算子范数 6.2.1 定义 CnC^nCn 上任一向量范数 ∥X∥V\Vert X\Vert_V∥X∥V​ 都产生一个矩阵范数 ∥A∥max⁡x≠0{∥AX∥V∥X∥V}\Vert A\Vert\max_{x\neq 0}\limits \{\frac{\Vert AX\Vert_V}{\Vert X\Vert_V}\}∥A∥x0max​{∥X∥V​∥AX∥V​​} ,X∈CnX\in C^nX∈Cn…

Linux 管理联网 测试网络连通性 -- Ping 命令详解 tracepath命令详解

测试网络的连通性 # 我们测试网络的连通性&#xff0c;一般就是使用的 PIng 命令 Ping &#xff1a; 一般格式 &#xff1a; ping [ 选项 ] < 目标主机名 或 IP 地址 > 常用选项 &#xff1a; - c 数字 &#xff1a; 用于 设定本命令发出的 ICMP 消息包的…

限量,Alibaba首发“Java成长笔记”,差距不止一点点

前言 本文是为了帮大家快速回顾了Java中知识点&#xff0c;这套面试手册涵盖了诸多Java技术栈的面试题和答案&#xff0c;相信可以帮助大家在最短的时间内用作面试复习&#xff0c;能达到事半功倍效果。 本来想将文件上传到github上&#xff0c;但由于文件太大有的都无法显示…

CentOS7使用yum安装Golang(超详细)

使用yum安装Golang前言一、go语言介绍二、yum安装golang1.安装go版本为1.19.41.1执行yum install go&#xff08;报错&#xff09;1.2配置go的安装源1.3执行yum install golang1.4查看go的安装版本2.安装go版本为 1.11rc2&#xff08;这个参考&#xff0c;不用操作&#xff09;…

Docker镜像的原理

centos7系统 包括2部分&#xff0c; linux内核&#xff0c;作用是提供操作系统的基本功能&#xff0c;和机器硬件交互&#xff0c;如何读取磁盘数据&#xff0c;管理网络&#xff0c;使用C编写的&#xff0c;由linus的开发团队&#xff0c;内核只提供操作系统的基本功能和特性…

修改嵌入式 ARM Linux 内核映像中的文件系统

zImage 是编译内核后在 arch/arm/boot 目录下生成的一个已经压缩过的内核映像。通常我们不会使用编译生成的原始内核映像 vmlinux&#xff0c;因其体积很大。因此&#xff0c;zImage 是我们最常见的内核二进制&#xff0c;可以直接嵌入到固件&#xff0c;也可以直接使用 qemu 进…

C++的OpenCV中cv::minAreaRect的返回角度的数值范围是多少?

版本不一样的时候&#xff0c;返回也不一样。 我使用opencv/4.5.5。 下图是使用minAreaRect判定的角度&#xff0c;可以看到&#xff0c;数值范围是[0,90]&#xff0c;看起来很离谱。 画出这张图使用的程序如下&#xff1a; C int main() {std::string prefix1 "/mn…

SpringMvc+Thymeleaf实现数据渲染

Thymeleaf是spring boot推荐使用的模板语法&#xff0c;它可以完全替代 JSP 。 从代码层次上讲&#xff1a;Thymeleaf是一个java类库&#xff0c;它是一个xml/xhtml/html5的模板引擎&#xff0c;可以作为mvc的web应用的view层。 Thymeleaf 提供spring标准方言和一个与 SpringMV…

Ui自动化概念+Web自动化测试框架介绍

目录 UI 1.UI自动化测试概念:我们先明确什么是UI 2.为什么对UI采用自动化测试? 3.什么项目适合做UI自动化测试? 4.UI自动化测试介入时机 5.UI自动化测试所属分类 Web自动化测试框架介绍 2.Selenium框架介绍及特点: Web自动化测试环境搭建 2.元素定位(一) idclassna…

【数据结构】栈与集合类Stack

目录 一、栈 二、Java中的集合类之Stack 1、介绍 2、构造方法 3、常用方法 1.push 2.pop 3.peek 4.search 5.empty 三、实现Stack 1、准备字段 2、实现判空 3、实现压栈 4、实现出栈 5、实现获取栈尾元素 6、指定元素到栈顶的距离 一、栈 栈(stack)是一种比较…

Redis高可用之哨兵模式(第二部分)

引言 接上一篇&#xff0c;今天我们来聊一聊Redis的高可用的第二个解决方案&#xff1a;哨兵模式。 一、Redis哨兵模式 哨兵模式&#xff08;sentinel&#xff09;是Redis提供的高可用的解决方案之一。由一个或者多个sentinel示例组成的sentinel系统&#xff0c;可以监听任意…

(Java高级教程)第二章Java多线程常见面试题-第二节:JUC(java.util.concurrent)

文章目录一&#xff1a;Callable接口二&#xff1a;ReentrantLock三&#xff1a;原子类四&#xff1a;信号量SemaphoreJUC&#xff1a;JUC是java.util.concurrent包的简称&#xff0c;目的就是为了更好的支持高并发任务。让开发者进行多线程编程时减少竞争条件和死锁的问题 一…