面试:如何设计高并发系统


写在前面

面试的时候经常会被问到如何设计一个高并发系统,很多人都只能说出缓存、读写分离、异步等几个常见方法,今天就系统全面总结一下这个问题,希望能帮助到大家。

什么是高并发系统

简单说就是你的系统要能支持瞬间大量的请求。比如淘宝双11、过年抢红包等。那如何量化的定义一个系统是不是高并发呢?有一些名称需要了解一下。

名词解释

QPS

QPS 全称是 Query Per Second ,含义是每秒查询数,即服务每秒处理完成的请求数。

TPS

TPS 全称是 Transaction Per Second ,含义是每秒事务数,即服务每秒处理完成的事务数。

RT

RT 全称是 Response Time ,含义是响应时间,即服务处理一次请求的平均响应时间。

并发量

并发量指的是客户端同时发起的请求数。注意,这里并不是服务处理的请求数。

服务并发处理数

服务端同时处理的请求数。这里要注意和并发量作区分。

用户数

用户数可以分为并发用户数、注册用户数和在线用户数。

并发用户数在真实线上环境下,指的是同时发起请求的用户数。在压测环境下,指的是压测工具中的虚拟用户数(Virutal User)。注意,并发用户数是一定会对系统产生压力的用户数。

注册用户数一般指的是数据库中存在的用户数,对系统不产生压力。

在线用户数指的是当前使用系统的,“挂” 在系统上的用户数,一般不对系统造成压力。

吞吐量

吞吐量,指的是系统服务在网络上传输的数据总和。

吞吐量不能作为衡量系统能力的指标,因为随着时间的拉长,吞吐量自然就上去了。比如滴水一天可能比全量开 1 分钟水龙头的自来水的流量还多,而我们的感受肯定是全量开水龙头的水流量大。因此,衡量系统吞吐能力,一般用单位时间内的吞吐量来衡量。即吞吐率。

衡量吞吐能力的指标一般有 QPS 、 TPS 、字节数/秒 和 页面数/秒等。

用户思考时间

在真实场景中,用户要完成某个业务(如支付)需要多个步骤,而每个步骤用户都需要一定的思考时间,这里每步操作之间的停顿的时间,即用户思考时间。

TP99

TP 的全称是 Top Percentile,即 Top 百分位数,此指标衡量的是某百分位处的请求响应时间,主要用于衡量对响应时间敏感的服务。比如:

  • TP90:按响应时间从小到大排列,位于 90% 处的响应时间;
  • TP99:按响应时间从小到大排列,位于 99% 处的响应时间;
  • TP999:按响应时间从小到大排列,位于 999% 处的响应时间。

TP 百分位数要求越高,则表示对性能要求越高。

PV

PV 的全称是 Page View,即页面访问量。

UV

UV 的全称是 Unique Visitor ,独立访客量,即去重后的访问用户数。

DAU

DAU 的全称是 Daily Active User,即日活跃用户数。

MAU

MAU 的全称是 Month Active User,即月活跃用户数。

名词概念之间的关系

了解了基本的名称概念后,还需要了解一些重要概念之间的关系,要知道有些指标概念之间是有一定的关系的,甚至是可以相互影响的。

下面介绍一些重要概念之间的关系。

QPS vs TPS

复杂场景下,用户要完成某个事务,可能需要访问多个或多次接口,此时:1TPS = nQPS。

对于简单场景,如完成一个事务,只需要访问一次一个接口,此时:1TPS = 1QPS。

并发用户数 vs 并发量

在多接口的复杂场景下,一个用户可能同时访问多个接口,此时对于系统来说,并发用户数 < 并发请求数。

在简单串行场景下,一个用户逐个访问单接口,此时对于系统来说,并发用户数 = 并发请求数。

并发量 vs 系统并发处理数

当并发量 > 系统并发处理能力时,并发量 > 系统并发处理数。

当并发量 <= 系统并发处理能力时,并发量 = 系统并发处理数。

TPS & RT & 系统并发处理数 & 用户思考时间

TPS = 系统并发处理数 / ( RT + 用户思考时间)。

系统并发处理数,是服务端同时处理的请求数。

RT 为系统平均响应时间,它的大小是网络传输时间总和、服务处理时间总和、数据库响应时间总和、缓存响应时间总和、磁盘IO时间总和以及其他时间的总和。

用户思考时间,对于单接口来说,是零;对于复杂接口(如完成支付事务)来说:用户思考时间 = 用户各操作步骤间隔时间。

TPS & RT & 并发数

系统 TPS 、RT 和并发数是相互影响的。其三者之间的影响关系,可以根据并发数的提升分为系统低负荷阶段、系统满负荷阶段和系统超负荷阶段。如下图所示。

在系统低负荷阶段(轻压力区),并发数很低,CPU 工作不饱和,随着并发数的增长, TPS 跟着增长, RT 几乎是平稳的。

随着并发数的增大,系统进入满负荷状态(重压力区),CPU 工作进入饱和状态,这时系统资源利用率达到最大值,TPS 达到最大值,RT 开始明显增长。

进一步增大并发数,系统就会进入超负荷状态(拐点区),这时系统开始处理大量请求,线程频繁切换,CPU load 超负荷,而此时真正处理的请求数反而会降低,最终导致 TPS 下降,RT指数级增长。

核心目标

要实现高并发系统,必须满足以下三个目标:

  • 高性能

高性能,即系统的并行处理能力,其主要的衡量指标是 RT 和并发处理数。根据系统的 TPS 计算公式,TPS = 并发处理数 / RT ,要想提高系统的性能,一是要提高系统并发处理能力,二是要降低系统处理的 RT 。

显而易见,高性能是高并发系统最主要的目标之一。比如你的系统响应时间是 10S ,别人的系统响应时间是 0.1S ,那用户体验是截然不同的。再比如你的系统只能支持 100 人来抢购,别人的系统能支持 10000 人来抢购,很可能用户来一次就不想再来了。

  • 高可用

高可用,即系统的稳定性。简单来讲,当秒杀活动的用户流量来临时,你的系统能不能稳定的处理这些流量,别流量一来,你的系统就崩掉了。

显而易见,系统的可用性也是高并发系统的最主要的目标之一。比如秒杀活动期间,流量一来,你的系统崩掉了,这时想必用户要崩溃了,不仅买不到自己想要的商品,也会影响平台口碑:招商招不来,用户不来买等等。

可用性的衡量指标一般用可用率来表示,可用率 = 正常运行时间 / 总运行时间。

业内一般用几个 9 来表示系统的可用性,比如可用性是 4 个 9 ,则表示可用率 = 99.99% ,总运行时间按一年时间来算的化,每年的不可用时间要小于 51.264m(356 * 24 * 60 * (1-99.99%))

  • 高伸缩性

高伸缩性,指的是系统能不能通过增减硬件配置,来扩容和缩容集群吞吐能力。

在实际线上场景中,平时流量一般不会特别大,而秒杀活动期间的流量可能是平时流量的数十倍,甚至是上百倍。从成本上考虑,假如一直用秒杀活动的硬件配置,显然太过浪费了。最好的效果是可以在平时用少量的硬件配置,在活动期间增加到大流量的配置。以此来充分有效的节约机器成本。

衡量高伸缩性的方式,就是要看系统的吞吐能力是不是能随着机器的扩容而增强,随着机器的缩容而降低。比如增加一倍的机器,能不能增加一倍的吞吐能力。

如何设计高并发系统

系统拆分

就是把单体系统拆分成多个微服务,一个微服务挂了不会影响其他微服务,通过兼容、容错等方法忽略当前微服务宕机带来的影响。

集群部署

一个服务部署多个实例,通过负载均衡、服务发现做调度

缓存

一般用redis缓存、内存缓存,将那些经常需要查询并且变动较小的缓存起来,可以做长时间缓存,也可以做短暂的缓存,当前请求有效。

CDN

加速静态资源访问

异步排队

使用消息队列,将请求或者耗时的操作放到消息队列中慢慢处理,实现削峰填谷。

分库分表

按照某个业务关键字分库分表,比如按租户分库,按月份分表等

池子化技术

很多耗时耗资源的第三方链接可以通过连接池实现服用。比如http连接、rpc连接、db连接、redis连接、线程等,通过池化技术先初始化好连接,待到要使用的时候直接用,用完放回去,下次接着用。

读写分离

一般是主从分离,一主多从,写主读从。

ES

Elasticsearch 分布式、高扩展、高实时的搜索与数据分析引擎,简称为ES。一般耗时的查询、统计、全文搜索可以用ES

熔断

当访问量突增或者某个机房遇到突发情况时,需要做一些降级措施,防止影响其他服务。比如通过开关,关闭某些请求或者服务,切换流量

限流

可以在接口上增加一些限流器来限制访问频率。

总结

参考

[1]架构系列:高并发架构的CDN知识介绍

[2]如何设计一个高并发系统?

[3]高并发系统,你真理解了吗?

[4]高并发系统设计 40 问

[5]高并发系统是如何设计的?

[6]字节三面:如何设计一个高并发系统


文章作者: Alex
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alex !
  目录