「 高并发系统设计 」 如何提高系统性能

news2024/9/19 19:48:22

「 高并发系统设计 」 如何提高系统性能

参考&鸣谢

⾼并发系统如何做性能优化? 玄明Hanko

高并发系统设计和优化的通用方法论 渝言家


文章目录

  • 「 高并发系统设计 」 如何提高系统性能
    • @[toc]
    • 一、高并发系统设计三大目标
      • 高性能
      • 高可用
      • 可扩展
    • 二、性能优化原则
      • 问题导向
      • 八二原则
      • 有数据支撑
      • 持续优化
    • 三、性能的度量指标
      • 平均值
      • 最大值
      • 分位值
    • 四、高并发下的性能优化
      • 提高系统的处理核心数
      • 减少单次任务响应时间
    • 五、小结

前言

在当今数字化时代,高并发系统设计成为数字产品和服务的核心挑战之一。随着用户规模的不断扩大和信息交互的激增,系统性能的优化变得尤为关键。本文将深入探讨提高系统性能的方法,聚焦于高性能、高可用和可扩展性这三大设计目标。通过问题导向的性能优化、八二原则的智慧应用,以及数据支撑的持续优化,我们将一步步揭示高并发系统设计的精髓。性能度量指标的明确、系统的并发能力评估、以及针对性能瓶颈的优化方案都将得到详尽的解析。


一、高并发系统设计三大目标

高性能

高性能是系统设计的灵魂所在。它意味着系统能够处理更多的用户并发请求,背后承载着对系统响应时间的极致追求。想象一下,每秒一次请求和每秒一万次请求,两者之间的差距,不仅仅是数字上的增长,更是用户体验上的天壤之别。

高可用

可用性是系统正常服务用户的时间,它直接关系到用户对系统的信赖度。全年不停机、无故障,这是用户对一个高可用系统的期待。在设计阶段就考虑系统的稳定性,是实现高可用的关键一步。

可扩展

可扩展性是面对峰值流量时系统的自我调整能力。考虑到流量的波动,尤其是峰值流量的冲击,我们需要设计系统能够在短时间内迅速扩容,以平稳地承担峰值流量。这是系统在高并发环境下必备的应变能力。

这三个目标交织在一起,构成了高并发系统设计的基石。在下面的内容中,我将带你逐步了解如何提升系统的性能,从而实现这三大目标。


二、性能优化原则

在进入性能优化的具体方法之前,我们先来明确一下性能优化的基本原则。

问题导向

性能优化绝对不能盲目进行,必须是问题导向的。优化的出发点必须是对系统存在的问题的深刻理解。盲目的提前优化可能增加系统的复杂性,浪费开发人员的时间,甚至因为优化措施与业务需求的折中而损害业务。

八二原则

性能优化遵循“八二原则”,即用20%的精力解决80%的性能问题。在优化过程中,要聚焦于主要矛盾,解决主要性能瓶颈,以最小的代价取得最大的性能提升。

有数据支撑

性能优化必须有数据支撑。在优化过程中,时刻监控和评估性能的变化,确保每一次优化都对系统的性能产生了实质性的提升。

持续优化

性能优化是一个持续不断的过程。高并发系统通常涉及复杂的业务逻辑,性能问题可能来自多个方面。在设定明确的性能目标的同时,我们需要持续寻找潜在的性能瓶颈,制定相应的优化方案,直到达到预期目标。

这些原则将为我们后续的性能优化提供明确的指引。在下一节中,我们将深入探讨常见性能问题的排查方式和优化手段,助你在高并发系统设计中游刃有余。


三、性能的度量指标

性能优化的第三点原则中提到,对于性能我们需要有度量的标准,有了数据才能明确目前存在的性能问题,也能够用数据来评估性能优化的效果。所以明确性能的度量指标十分重要。

一般来说,度量性能的指标是系统接口的响应时间,但是单次的响应时间是没有意义的,你需要知道一段时间的性能情况是什么样的。所以,我们需要收集这段时间的响应时间数据,然后依据一些统计方法计算出特征值,这些特征值就能够代表这段时间的性能情况。我们常见的特征值有以下几类。

平均值

顾名思义,平均值是把这段时间所有请求的响应时间数据相加,再除以总请求数。平均值可以在一定程度上反应这段时间的性能,但它敏感度比较差,如果这段时间有少量慢请求时,在平均值上并不能如实的反应。

举个例子,假设我们在 30s 内有 10000 次请求,每次请求的响应时间都是 1ms,那么这段时间响应时间平均值也是 1ms。这时,当其中 100 次请求的响应时间变成了 100ms,那么整体的响应时间是 (100 * 100 + 9900 * 1) / 10000 = 1.99ms。你看,虽然从平均值上来看仅仅增加了不到 1ms,但是实际情况是有 1% 的请求(100/10000)的响应时间已经增加了 100 倍。所以,平均值对于度量性能来说只能作为一个参考。

最大值

这个更好理解,就是这段时间内所有请求响应时间最长的值,但它的问题又在于过于敏感了。

还拿上面的例子来说,如果 10000 次请求中只有一次请求的响应时间达到 100ms,那么这段时间请求的响应耗时的最大值就是 100ms,性能损耗为原先的百分之一,这种说法明显是不准确的。

分位值

分位值有很多种,比如 90 分位、95 分位、75 分位。以 90 分位为例,我们把这段时间请求的响应时间从小到大排序,假如一共有 100 个请求,那么排在第 90 位的响应时间就是 90 分位值。分位值排除了偶发极慢请求对于数据的影响,能够很好地反应这段时间的性能情况,分位值越大,对于慢请求的影响就越敏感。

img

在我来看,分位值是最适合作为时间段内,响应时间统计值来使用的,在实际工作中也应用最多。除此之外,平均值也可以作为一个参考值来使用。

我在上面提到,脱离了并发来谈性能是没有意义的,我们通常使用吞吐量或者同时在线用户数来度量并发和流量,使用吞吐量的情况会更多一些。但是你要知道,这两个指标是呈倒数关系的。

这很好理解,响应时间 1s 时,吞吐量是每秒 1 次,响应时间缩短到 10ms,那么吞吐量就上升到每秒 100 次。所以,一般我们度量性能时都会同时兼顾吞吐量和响应时间,比如我们设立性能优化的目标时通常会这样表述:在每秒 1 万次的请求量下,响应时间 99 分位值在 10ms 以下。

那么,响应时间究竟控制在多长时间比较合适呢?这个不能一概而论。

从用户使用体验的角度来看,200ms 是第一个分界点:接口的响应时间在 200ms 之内,用户是感觉不到延迟的,就像是瞬时发生的一样。而 1s 是另外一个分界点:接口的响应时间在 1s 之内时,虽然用户可以感受到一些延迟,但却是可以接受的,超过 1s 之后用户就会有明显等待的感觉,等待时间越长,用户的使用体验就越差。所以,健康系统的 99 分位值的响应时间通常需要控制在 200ms 之内,而不超过 1s 的请求占比要在 99.99% 以上。

现在你了解了性能的度量指标,那我们再来看一看,随着并发的增长我们实现高性能的思路是怎样的。


四、高并发下的性能优化

假如说,你现在有一个系统,这个系统中处理核心只有一个,执行的任务的响应时间都在 10ms,它的吞吐量是在每秒 100 次。那么我们如何来优化性能从而提高系统的并发能力呢?主要有两种思路:一种是提高系统的处理核心数,另一种是减少单次任务的响应时间。

提高系统的处理核心数

提高系统的处理核心数就是增加系统的并行处理能力,这个思路是优化性能最简单的途径。拿上一个例子来说,你可以把系统的处理核心数增加为两个,并且增加一个进程,让这两个进程跑在不同的核心上。这样从理论上,你系统的吞吐量可以增加一倍。当然了,在这种情况下,吞吐量和响应时间就不是倒数关系了,而是:吞吐量 = 并发进程数 / 响应时间。

计算机领域的阿姆达尔定律(Amdahl’s law)是吉恩·阿姆达尔在 1967 年提出的。它描述了并发进程数与响应时间之间的关系,含义是在固定负载下,并行计算的加速比,也就是并行化之后效率提升情况,可以用下面公式来表示:

(Ws + Wp) / (Ws + Wp/s)

其中,Ws 表示任务中的串行计算量,Wp 表示任务中的并行计算量,s 表示并行进程数。从这个公式我们可以推导出另外一个公式:

1/(1-p+p/s)

其中,s 还是表示并行进程数,p 表示任务中并行部分的占比。当 p 为 1 时,也就是完全并行时,加速比与并行进程数相等;当 p 为 0 时,即完全串行时,加速比为 1,也就是说完全无加速;当 s 趋近于无穷大的时候,加速比就等于 1/(1-p),你可以看到它完全和 p 成正比。特别是,当 p 为 1 时,加速比趋近于无穷大。

以上公式的推导过程有些复杂,你只需要记住结论就好了。

我们似乎找到了解决问题的银弹,是不是无限制地增加处理核心数就能无限制地提升性能,从而提升系统处理高并发的能力呢?很遗憾,随着并发进程数的增加,并行的任务对于系统资源的争抢也会愈发严重。在某一个临界点上继续增加并发进程数,反而会造成系统性能的下降,这就是性能测试中的拐点模型。

img

从图中你可以发现,并发用户数处于轻压力区时,响应时间平稳,吞吐量和并发用户数线性相关。而当并发用户数处于重压力区时,系统资源利用率到达极限,吞吐量开始有下降的趋势,响应时间也会略有上升。这个时候,再对系统增加压力,系统就进入拐点区,处于超负荷状态,吞吐量下降,响应时间大幅度上升。

所以我们在评估系统性能时通常需要做压力测试,目的就是找到系统的“拐点”,从而知道系统的承载能力,也便于找到系统的瓶颈,持续优化系统性能。

说完了提升并行能力,我们再看看优化性能的另一种方式:减少单次任务响应时间。

减少单次任务响应时间

想要减少任务的响应时间,首先要看你的系统是 CPU 密集型还是 IO 密集型的,因为不同类型的系统性能优化方式不尽相同。

CPU 密集型系统中,需要处理大量的 CPU 运算,那么选用更高效的算法或者减少运算次数就是这类系统重要的优化手段。比方说,如果系统的主要任务是计算 Hash 值,那么这时选用更高性能的 Hash 算法就可以大大提升系统的性能。发现这类问题的主要方式,是通过一些 Profile 工具来找到消耗 CPU 时间最多的方法或者模块,比如 Linux 的 perf、eBPF 等。

IO 密集型系统指的是系统的大部分操作是在等待 IO 完成,这里 IO 指的是磁盘 IO 和网络 IO。我们熟知的系统大部分都属于 IO 密集型,比如数据库系统、缓存系统、Web 系统。这类系统的性能瓶颈可能出在系统内部,也可能是依赖的其他系统,而发现这类性能瓶颈的手段主要有两类。

第一类是采用工具,Linux 的工具集很丰富,完全可以满足你的优化需要,比如网络协议栈、网卡、磁盘、文件系统、内存,等等。这些工具的用法很多,你可以在排查问题的过程中逐渐积累。除此之外呢,一些开发语言还有针对语言特性的分析工具,比如说 Java 语言就有其专属的内存分析工具。

另外一类手段就是可以通过监控来发现性能问题。在监控中我们可以对任务的每一个步骤做分时的统计,从而找到任务的哪一步消耗了更多的时间。这一部分在演进篇中会有专门的介绍,这里就不再展开了。

那么找到了系统的瓶颈点,我们要如何优化呢?优化方案会随着问题的不同而不同。比方说,如果是数据库访问慢,那么就要看是不是有锁表的情况、是不是有全表扫描、索引加得是否合适、是否有 JOIN 操作、需不需要加缓存,等等;如果是网络的问题,就要看网络的参数是否有优化的空间,抓包来看是否有大量的超时重传,网卡是否有大量丢包等。

总而言之,“兵来将挡水来土掩”,我们需要制定不同的性能优化方案来应对不同的性能问题。

五、小结

在高并发系统设计中,追求高性能、高可用和可扩展性是永恒的目标。性能优化是实现这些目标的关键一环,而充分了解性能度量指标和灵活运用优化思路,则是提升系统性能的有效途径。

不同系统面临不同的性能问题,因此需要有针对性地选择性能优化方案。持续的性能监控和优化是一个迭代的过程,通过不断地寻找性能瓶颈并制定相应的优化策略,可以使系统在高并发环境下更加稳定、高效地运行。

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

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

相关文章

【硬核HeyGen平替】在window平台上使用MyHeyGen

最近在研究HeyGen的平替开源项目,然后发现了MyHeyGen这个项目,但是文档上面并没有说明如果在window平台上使用,考虑到非window平台安装显卡驱动什么的比较繁琐,所以尝试硬着头皮干... 前提 开源项目中所需的环境准备要先准备好 1…

qgis添加xyz栅格瓦片

方式1:手动一个个添加 左侧浏览器-XYZ Tiles-右键-新建连接 例如添加高德瓦片地址 https://wprd01.is.autonavi.com/appmaptile?langzh_cn&size1&style7&x{x}&y{y}&z{z} 双击即可呈现 收集到的一些图源,仅供参考,其中一…

中断方式的数据接收

中断接收简介 回顾之前的代码 之前的代码是 等待标志位RXNE位为1才有数据 进而读取数据存放在变量c中 再根据c变量的数据是为0还是为1进而编写灯亮灭的代码 if语句 但这样的代码明显不符合裸机多任务的编程模型 因为在while中为进程 进程执行的时间不能大于5ms 但是while&…

Linux实验四:shell程序设计: shell控制语句

实验目的 进一步巩固shell程序设计语言基本语法,加深对所学知识理解。 实验内容 要求学生掌握以下内容 (1)条件表达式 (2)判断和分支语句 (3)循环语句 (4)函数 实验内容 1 条件表达式 $ test 10 -gt 5 // 算数表达式 10>5 $ echo $? //显示上述表达…

〔004〕虚幻 UE5 像素流部署

✨ 目录 ▷ 启用像素流插件▷ 打包项目▷ 下载环境包▷ 手动下载▷ 安装信令服务器环境▷ 启动信令服务器▷ 设置启动参数▷ 启动程序▷ 网页运行▷ 开启触控界面▷ 启用像素流插件 打开虚幻启动程序,选择 编辑 后点击 插件在插件列表中搜索 pixel streaming 关键字,勾选后重…

杨传辉:从一体化架构,到一体化产品,为关键业务负载打造一体化数据库

在刚刚结束的年度发布会上,OceanBase正式推出一体化数据库的首个长期支持版本 4.2.1 LTS,这是面向 OLTP 核心场景的全功能里程碑版本,相比上一个 3.2.4 LTS 版本,新版本能力全面提升,适应场景更加丰富,有更…

北邮22级信通院数电:Verilog-FPGA(11)第十一周实验(2)设计一个24秒倒计时器

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 一.代码部分 1.1 counter_24.v 1.2 divid…

【Flink】Standalone运行模式

独立模式是独立运行的,不依赖任何外部的资源管理平台;当然独立也是有代价的:如果资源不足,或者出现故障,没有自动扩展或重分配资源的保证,必须手动处理。所以独立模式一般只用在开发测试或作业非常少的场景…

Spring Boot集成MyBatis实现多数据源访问的“秘密”

文章目录 为什么需要多数据源?Spring Boot集成MyBatis的基础配置使用多数据源小结 🎉Spring Boot集成MyBatis实现多数据源访问的“秘密” ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页:IT陈寒的博客🎈该系列文章专栏&…

TIDB拓扑结构

TiDB Server:SQL层,负责接受客户端的连接,执行SQL解析和优化,最终生成分布式执行计划。TiDB Server为无状态的,可增加节点负载均衡。 PD (Placement Driver) Server:整个TiDB集群的元信息管理模块&#xf…

在全球碳市场中崭露头角的中碳CCNG

在全球气候治理的大背景下,中国碳中和发展集团有限公司(简称中国碳中和)正在成为全球碳交易市场的一个重要参与者。随着国际社会对碳排放的日益关注,中国碳中和凭借其在碳资产开发、咨询与管理等领域的深厚积累,正成为…

010 OpenCV中的4种平滑滤波

目录 一、环境 二、平滑滤波 2.1、均值滤波 2.2、高斯滤波 2.3、中值滤波 2.4、双边滤波 三、完整代码 一、环境 本文使用环境为: Windows10Python 3.9.17opencv-python 4.8.0.74 二、平滑滤波 2.1、均值滤波 在OpenCV库中,blur函数是一种简…

vue3 echarts滑动条datazoom怎么设置圆角

效果图 代码 dataZoom: [// {// type: "slider",// show: val.Ydata.length > 8 ? true : false, //隐藏或显示(true)组件// backgroundColor: "#1c3030", // 组件的背景颜色。// fillerColor: "#74adb2", // 选…

小叶子钢琴智能陪练 助力打牢钢琴基础

孩子在练琴过程中,经常会出现错音错节奏,为了能够帮助她更高效的练琴,最近开始使用智能钢琴陪练工具——小叶子钢琴智能陪练。 身边也有很多朋友在用这款应用,它比较知名的功能就是三大练琴模式,也就是识谱模式、提升…

Java Web 实战 21 - 用 Servlet 实现一个Hello World

用 Servlet 来写一个 Hello World~ 一 . 基本部署方式1.1 创建 Servlet 项目1.2 引入依赖1.3 创建目录1.4 编写代码继承 HttpServlet重写 doGet 方法删除 super 方法加上 WebServlet 注解写业务逻辑 1.5 打包1.6 部署1.7 验证1.8 小结 二 . 更方便的部署方式2.1 Smart Tomcat 的…

详解开源数据库审计平台Yearning

基本概念 数据库审计(简称DBAudit)能够实时记录网络上的数据库活动,对数据库操作进行细粒度审计的合规性管理,对数据库遭受到的风险行为进行告警,对攻击行为进行阻断。它通过对用户访问数据库行为的记录、分析和汇报&…

python树的双亲存储结构

这种存储结构是一种顺序存储结构,采用元素形如“[结点值,双亲结点索引]”的列表表示。通常每个结点有唯一的索引(或者伪地址),根结点的索引为0,它没有双亲结点,其双亲结点的索引为-1。例如,所示的树对应的双…

项目中常用的 19 条 SQL 优化宝典

一、EXPLAIN 做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划。 下面来个简单的示例,标注(1,2,3,4,5)我们要重点关注的数据 type列,连接类型。一个好的sql语句至少要达到range级别。杜绝出现all级别 key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引…

Cobalt Strike之反向上线操作

前言 ​ Cobalt Strike 使用 GUI 框架 SWING(一种java GUI的库)开发,攻击者可通过CS木马在 beacon 元数据中注入恶意 HTML 标签,使得Cobalt Strike对其进行解析并且加载恶意代码(类似XSS攻击),…

【Proteus仿真】【51单片机】智能垃圾桶设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器,使用报警模块、LCD1602液晶模块、按键模块、人体红外传感器、HCSR04超声波、有害气体传感器、SG90舵机等。 主要功能: 系统运行后&#xf…