01 _ 高并发系统:它的通用设计方法是什么?

我们知道,高并发代表着大流量,高并发系统设计的魅力就在于我们能够凭借自己的聪明才智设计巧妙的方案,从而抵抗巨大流量的冲击,带给用户更好的使用体验。这些方案好似能操纵流量,让流量更加平稳地被系统中的服务和组件处理。

来做个简单的比喻吧。

从古至今,长江和黄河流域水患不断,远古时期大禹曾拓宽河道,清除淤沙让流水更加顺畅;都江堰作为史上最成功的治水案例之一,用引流将岷江之水分流到多个支流中,以分担水流压力;三门峡和葛洲坝通过建造水库将水引入水库先存储起来,然后再想办法把水库中的水缓缓地排出去,以此提高下游的抗洪能力。

而我们在应对高并发大流量时也会采用类似“抵御洪水”的方案,归纳起来共有三种方法。

  • Scale-out(横向扩展):分而治之是一种常见的高并发系统设计方法,采用分布式部署的方式把流量分流开,让每个服务器都承担一部分并发和流量。

  • 缓存:使用缓存来提高系统的性能,就好比用“拓宽河道”的方式抵抗高并发大流量的冲击。

  • 异步:在某些场景下,未处理完成之前我们可以让请求先返回,在数据准备好之后再通知请求方,这样可以在单位时间内处理更多的请求。

简单介绍了这三种方法之后,我再详细地带你了解一下,这样当你在设计高并发系统时就可以有考虑的方向了。当然了,这三种方法会细化出更多的内容,我会在后面的课程中深入讲解。

首先,我们先来了解第一种方法:Scale-out。

Scale-up vs Scale-out

著名的“摩尔定律”是由Intel的创始人之一戈登·摩尔于1965年提出的。这个定律提到集成电路上可容纳的晶体管的数量约每隔两年会增加一倍。

后来,Intel首席执行官大卫·豪斯提出“18个月”的说法,即预计18个月会将芯片的性能提升一倍,这个说法广为流传。

摩尔定律虽然描述的是芯片的发展速度,但我们可以延伸为整体的硬件性能,从20世纪后半叶开始,计算机硬件的性能是指数级演进的。

直到现在,摩尔定律依然生效,在半个世纪以来的CPU发展过程中,芯片厂商靠着在有限面积上做更小的晶体管的黑科技,大幅度地提升着芯片的性能。从第一代集成电路上只有十几个晶体管,到现在一个芯片上动辄几十亿晶体管的数量,摩尔定律指引着芯片厂商完成了技术上的飞跃。

但是有专家预测,摩尔定律可能在未来几年之内不再生效,原因是目前的芯片技术已经做到了5nm级别,在工艺上可以突破的空间不大,可能达不到摩尔定律提到的每18个月翻一番的速度了。此时,双核和多核技术的产生拯救了摩尔定律,这些技术的思路是将多个CPU核心压在一个芯片上,从而大大提升CPU的并行处理能力。

我们在高并发系统设计上也沿用了同样的思路,将类似追逐摩尔定律不断提升CPU性能的方案叫做Scale-up(纵向扩展),把类似CPU多核心的方案叫做Scale-out,这两种思路在实现方式上是完全不同的。

  • Scale-up通过购买性能更好的硬件来提升系统的并发处理能力,比方说目前系统4核4G每秒可以处理200次请求,那么如果要处理400次请求呢?很简单,我们把机器的硬件提升到8核8G(硬件资源的提升可能不是线性的,这里仅为参考)。

  • Scale-out则是另外一个思路,它通过将多个低性能的机器组成一个分布式集群来共同抵御高并发流量的冲击。沿用刚才的例子,我们可以使用两台4核4G的机器来处理那400次请求。

那么什么时候选择Scale-up,什么时候选择Scale-out呢?一般来讲,在我们系统设计初期会考虑使用Scale-up的方式,因为这种方案足够简单,所谓能用堆砌硬件解决的问题就用硬件来解决,但是当系统并发超过了单机的极限时,我们就要使用Scale-out的方式。

Scale-out虽然能够突破单机的限制,但也会引入一些复杂问题。比如,如果某个节点出现故障如何保证整体可用性?当多个节点有状态需要同步时如何保证状态信息在不同节点的一致性?如何做到使用方无感知的增加和删除节点?其中每一个问题都涉及很多的知识点,我会在后面的课程中深入地讲解,这里暂时不展开了。

说完了Scale-out,我们再来看看高并发系统设计的另一种方法:缓存。

使用缓存提升性能

Web 2.0是缓存的时代,这一点毋庸置疑。缓存遍布在系统设计的每个角落,从操作系统到浏览器,从数据库到消息队列,任何略微复杂的服务和组件中你都可以看到缓存的影子。我们使用缓存的主要作用是提升系统的访问性能,在高并发的场景下就可以支撑更多用户的同时访问。

那么为什么缓存可以大幅度提升系统的性能呢?我们知道数据是放在持久化存储中的,一般的持久化存储都是使用磁盘作为存储介质的,而普通磁盘数据由机械手臂、磁头、转轴、盘片组成,盘片又分为磁道、柱面和扇区,盘片构造图我放在下面了。

盘片是存储介质,每个盘片被划分为多个同心圆,信息都被存储在同心圆之中,这些同心圆就是磁道。在磁盘工作时盘片是在高速旋转的,机械手臂驱动磁头沿着径向移动,在磁道上读取所需要的数据。我们把磁头寻找信息花费的时间叫做寻道时间。

普通磁盘的寻道时间是10ms左右,而相比于磁盘寻道花费的时间,CPU执行指令和内存寻址的时间都是在ns(纳秒)级别,从千兆网卡上读取数据的时间是在μs(微秒)级别。所以在整个计算机体系中磁盘是最慢的一环,甚至比其它的组件要慢几个数量级。因此我们通常使用以内存作为存储介质的缓存,以此提升性能。

当然,缓存的语义已经丰富了很多,我们可以将任何降低响应时间的中间存储都称为缓存。缓存的思想遍布很多设计领域,比如在操作系统中CPU有多级缓存,文件有Page Cache缓存,你应该有所了解。

异步处理

异步也是一种常见的高并发设计方法,在很多文章和演讲中都能听到这个名词,与之共同出现的还有它的反义词:同步。比如分布式服务框架Dubbo中有同步方法调用和异步方法调用,IO模型中有同步IO和异步IO。

那么什么是同步,什么是异步呢?以方法调用为例,同步调用代表调用方要阻塞等待被调用方法中的逻辑执行完成。这种方式下,当被调用方法响应时间较长时,会造成调用方长久的阻塞,在高并发下会造成整体系统性能下降甚至发生雪崩。

异步调用恰恰相反,调用方不需要等待方法逻辑执行完成就可以返回执行其他的逻辑,在被调用方法执行完毕后再通过回调、事件通知等方式将结果反馈给调用方。

异步调用在大规模高并发系统中被大量使用,比如我们熟知的12306网站。当我们订票时,页面会显示系统正在排队,这个提示就代表着系统在异步处理我们的订票请求。在12306系统中查询余票、下单和更改余票状态都是比较耗时的操作,可能涉及多个内部系统的互相调用,如果是同步调用就会像12306刚刚上线时那样,高峰期永远不可能下单成功。

而采用异步的方式,后端处理时会把请求丢到消息队列中,同时快速响应用户,告诉用户我们正在排队处理,然后释放出资源来处理更多的请求。订票请求处理完之后,再通知用户订票成功或者失败。

处理逻辑后移到异步处理程序中,Web服务的压力小了,资源占用的少了,自然就能接收更多的用户订票请求,系统承受高并发的能力也就提升了。

既然我们了解了这三种方法,那么是不是意味着在高并发系统设计中,开发一个系统时要把这些方法都用上呢?当然不是,系统的设计是不断演进的。

罗马不是一天建成的,系统的设计也是如此。不同量级的系统有不同的痛点,也就有不同的架构设计的侧重点。如果都按照百万、千万并发来设计系统,电商一律向淘宝看齐,IM全都学习微信和QQ,那么这些系统的命运一定是灭亡。

因为淘宝、微信的系统虽然能够解决同时百万、千万人同时在线的需求,但其内部的复杂程度也远非我们能够想象的。盲目地追从只能让我们的架构复杂不堪,最终难以维护。就拿从单体架构往服务化演进来说,淘宝也是在经历了多年的发展后,发现系统整体的扩展能力出现问题时,开始启动服务化改造项目的。

我之前也踩过一些坑,参与的一个创业项目在初始阶段就采用了服务化的架构,但由于当时人力有限,团队技术积累不足,因此在实际项目开发过程中,发现无法驾驭如此复杂的架构,也出现了问题难以定位、系统整体性能下降等多方面的问题,甚至连系统宕机了都很难追查到根本原因,最后不得不把服务做整合,回归到简单的单体架构中。

所以我建议一般系统的演进过程应该遵循下面的思路:

  • 最简单的系统设计满足业务需求和流量现状,选择最熟悉的技术体系。

  • 随着流量的增加和业务的变化修正架构中存在问题的点,如单点问题、横向扩展问题、性能无法满足需求的组件。在这个过程中,选择社区成熟的、团队熟悉的组件帮助我们解决问题,在社区没有合适解决方案的前提下才会自己造轮子。

  • 当对架构的小修小补无法满足需求时,考虑重构、重写等大的调整方式以解决现有的问题。

以淘宝为例,当时在业务从0到1的阶段是通过购买的方式快速搭建了系统。而后,随着流量的增长,淘宝做了一系列的技术改造来提升高并发处理能力,比如数据库存储引擎从MyISAM迁移到InnoDB,数据库做分库分表,增加缓存,启动中间件研发等。

当这些都无法满足时就考虑对整体架构做大规模重构,比如说著名的“五彩石”项目让淘宝的架构从单体演进为服务化架构。正是通过逐步的技术演进,淘宝才进化出如今承担过亿QPS的技术架构。

归根结底一句话:高并发系统的演进应该是循序渐进,以解决系统中存在的问题为目的和驱动力的。

小结

介绍了高并发系统设计的三种通用方法:Scale-out、缓存和异步。这三种方法可以在做方案设计时灵活地运用,但它不是具体实施的方案,而是三种思想,在实际运用中会千变万化。

就拿Scale-out来说,数据库一主多从、分库分表、存储分片都是它的实际应用方案。而我们需要注意的是,在应对高并发大流量的时候,系统是可以通过增加机器来承担流量冲击的,至于要采用什么样的方案还是要具体问题具体分析。

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

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

相关文章

阻塞队列

文章目录 阻塞队列BlockingQueue实现阻塞队列生产者消费者模型 阻塞队列 阻塞队列是什么呢? 阻塞队列是一种特殊的队列,满足队列的基本要求 - 先进先出。同时阻塞队列使一种线程安全的数据结构。不过阻塞队列相较于普通队列也有着它的特殊之处。 线程安…

思维模型 波纹效应

本系列文章 主要是 分享 思维模型,涉及各个领域,重在提升认知。小变化,大影响。 1 波纹效应的应用 1.1 波纹效应在市场中的应用 2008 年,美国金融危机爆发,导致全球经济陷入衰退。这场危机的起因是美国房地产市场的崩…

GIS入门,开源 JavaScript二维地图引擎OpenLayers介绍

VueOpenLayers中文教程推荐,不同于OpenLayers官方文档使用htmljs原生原生教程,博主专栏包含大量vue整合案例和实际开发案例,非常适合地图开发小白快速入门。 vue整合OpenLayers6入门教程: 《VueOpenLayers入门教程汇总目录》vue整…

Linux操作系统之apt常用命令记录

文章目录 apt 命令apt 语法apt 常用命令列出所有可更新的软件清单命令升级软件包列出可更新的软件包及版本信息升级软件包,升级前先删除需要更新软件包安装指定的软件命令:安装多个软件包:更新指定的软件命令显示软件包具体信息,例如&#xf…

C语言进阶之路-运算符小怪篇

目录 一、学习目标 二、运算符详谈 算术运算符 关系运算符 逻辑运算符 位运算符 特殊运算符 条件运算符 sizeof 运算符 打怪实战 三、控制流 二路分支 多路分支 const while与 do…while循环 语法: for循环 break与continue goto语句&#xff08…

MySQL MHA高可用架构搭建

快捷查看指令 ctrlf 进行搜索会直接定位到需要的知识点和命令讲解(如有不正确的地方欢迎各位小伙伴在评论区提意见,博主会及时修改) MySQL MHA高可用架构搭建 MHA(Master HA)是一款开源的 MySQL 的高可用程序&#xf…

如何获得微软MVP徽章

要成为微软MVP,需要在特定领域成为专家,并积极参与社区,为其他人提供帮助和支持。以下是一些步骤可以帮助你成为MVP: 在特定领域成为专家:要成为MVP,需要在某个领域具有专业知识和经验。这可以通过阅读相关…

ffmpeg下载与配置环境变量

FFmpeg 是一个强大的多媒体框架,可以让用户处理和操纵音频和视频文件。具有易于使用的界面,用户可以在 Windows、Mac 或 Linux Ubuntu 系统上下载 FFmpeg 并将其提取到文件夹中。然后,该软件可以加入 PATH 环境变量中就可以快捷的使用软件了.…

使用 STM32 读取和解析 NTC 热敏电阻的数值

本文介绍了如何利用 STM32 微控制器读取和解析 NTC(Negative Temperature Coefficient)热敏电阻的数值。首先,我们将简要介绍 NTC 热敏电阻的原理和特性。接下来,我们将详细讨论如何设计电路连接和采用合适的 STM32 外设进行数值读…

Element-Plus 图标自动导入

🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🌺 仓库主页: Gitee 💫 Github 💫 GitCode 💖 欢迎点赞…

迎接“全全闪”时代 XSKY星辰天合发布星海架构和星飞产品

11 月 17 日消息,北京市星辰天合科技股份有限公司(简称:XSKY星辰天合)在北京首钢园举办了主题为“星星之火”的 XSKY 星海全闪架构暨星飞存储发布会。 (图注:XSKY星辰天合 CEO 胥昕) XSKY星辰天…

SQL sever2008中的游标

目录 一、游标概述 二、游标的实现 三、优缺点 3.1优点: 3.2缺点: 四、游标类型 4.1静态游标 4.2动态游标 4.3只进游标 4.4键集驱动游标 4.5显示游标: 4.6隐式游标 五、游标基本操作 5.1声明游标 5.1.1.IS0标准语法 5.1.1.1语…

【经典小练习】输出文件路径名

文章目录 🌹问题✨思路🍔代码🛸读取文件,并把文件名保存到文件中 对指定目录下的所有 Java 文件进行编译、打包等处理; 查找指定目录下所有包含特定字符串的 Java 文件; 统计指定目录下所有 Java 文件的行数…

【数据结构实验】树(一)构建二叉查找树(BST)

文章目录 1. 引言2. 二叉查找树3. 实验内容3.1 实验题目(一)输入要求(二)输出要求 3.2 算法实现1. 数据结构2. 全局变量3. 中序遍历函数InOrder4. 二叉查找树的构建函数T5. 主函数 3.3 代码整合 4. 实验结果 1. 引言 二叉查找树&a…

【Linux】进程间通信——system V共享内存、共享内存的概念、共享内存函数、system V消息队列、信号量

文章目录 进程间通信1.system V共享内存1.1共享内存原理1.2共享内存数据结构1.3共享内存函数 2.system V消息队列2.1消息队列原理 3.system V信号量3.1信号量原理3.2进程互斥 4.共享内存的使用示例 进程间通信 1.system V共享内存 1.1共享内存原理 共享内存区是最快的IPC形式…

从零开始搭建博客网站-----源代码试部署

拿到了该项目的源码,先尝试是否可以成功部署,详细的部署视频地址 后端项目部署 先把maven配置好,都改成自己下载的maven地址 文件编码改成utf-8,防止配置文件乱码 如果maven是刚下的,要改一下下载包的地址&#xff0…

ASP产品通过网络安全专用产品安全认证

什么是网络安全专用产品安全检测? 网络安全专用产品安全检测是指对网络关键设备和网络安全专用产品进行安全性评估和检测,以确保其符合相关标准和法规的要求,能够有效地抵御网络攻击和威胁。该检测由具备资格的机构进行,采用认证…

bugku 渗透测试

场景1 查看源代码 场景2 用dirsearch扫描一下看看 ok看到登录的照应了第一个提示 进去看看 不出所料 随便试试admin/admin进去了 在基本设置里面看到falg 场景3 确实是没啥想法了 找到php在线运行 检查网络,我们发现这个php在线运行会写入文件 那我们是不是写…

【SpringCloud】设计原则之单一职责与服务拆分

一、设计原则之单一职责 设计原则很重要的一点就是简单,单一职责也就是所谓的专人干专事 一个单元(一个类、函数或微服务)应该有且只有一个职责 无论如何,一个微服务不应该包含多于一个的职责 职责单一的后果之一就是职责单…

Java网络爬虫实战

List item 文章目录 ⭐️写在前面的话⭐️📌What is it?分类网络爬虫按照系统结构和实现技术,大致可以分为以下几种类型:通用网络爬虫(General Purpose Web Crawler)、聚焦网络爬虫(Focused Web Crawler&a…