高并发系统的名词概念、核心目标以及解决方案

经过了一年的时间,我将支付系统的 TPS 从几百提升到了数千,涉及到的系统大概有五六十个,期间遇到了很多高并发场景下的问题。在提升系统性能的过程中,除了分析和解决这一个个具体的问题外,更多的是随着经验的积累,加深了我对高并发系统的理解。

提到高并发系统,我们要明白什么样的系统算是高并发系统?用哪些指标可以衡量它?高并发系统的核心目标是什么?以及高并发系统的解决方案有哪些?

本文就谈一谈我对高并发系统的理解。内容包括高并发系统的相关名词概念、核心目标以及解决方案。

名词概念

提到性能优化,首先要清晰的理解系统性能相关的基本概念。如果对这些基本概念都不能清晰的理解,那么对整个系统性能相关的基本概念、衡量标准、优化方法等都将是模糊的,就更不用谈负责和提升系统性能了。

下面是常见的系统系统相关的名词概念。

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

image.png

在系统低负荷阶段(轻压力区),并发数很低,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%))

核心目标三:高伸缩性

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

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

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

高并发系统的解决方案

要实现一个高并发系统,就是要围绕着高并发系统的三个核心目标展开,对高性能、高可用和高伸缩性分别制定解决方案。

高性能的解决方案

提升系统性能总的策略是提供系统并发处理能力降低系统响应时间

最简单直接的方式,可以通过提升单机的硬件来提升系统性能,如增加内存、增加高配的CPU、磁盘使用SSD等。此外,还可以通过优化算法、使用缓存等方式,来提升系统自身的性能。

下面看常见的提升系统并发处理能力的方案。

  • 服务集群部署,现在的系统一般都是采用集群的方式来部署,多台机器的性能肯定要好于单机的。
  • 数据库分库分表,现在大型系统,因为数据量巨大,而单机数据库的处理能力有限,这时就需要将单库拆成多库,使用多库,也就使用了多机,这样既解决了数据库性能瓶颈,也能利用多台机器的资源参与处理。
  • 使用 MQ 削峰,减少系统资源的占用时间。

我们知道,系统的响应时间是网络传输时间总和、服务处理时间总和、数据库响应时间总和、缓存响应时间总和、磁盘IO时间总和以及其他时间的总和,所以,想降低系统响应时间,就是通过降低这些各个子任务的响应时间,来降低总的响应时间。

降低系统响应时间一般有以下方案。

  • 减少调用链路和网络传输数据大小,来减少网络传输时间。比如合理优化调用层级,并不是服务拆分的越细越好;再如远程接口尽可能的做适配设计,减少没必要的返回字段等。
  • 使用多线程并发处理,降低系统串行处理的时间。比如一个服务接口可能需要查询多个下游服务,这时可以使用多线程并行查询。
  • 设计多级缓存,如本地缓存、分布式缓存等,来减少数据库的访问、减少网络传输等。
  • 数据库分库分表,库和表多了,单表数据量减少了,性能自然也上去了。
  • 数据库索引优化,降低数据库访问时间。
  • 减少磁盘IO操作,如多次访问数据库改为批量访问、采用性能优秀的日志框架等。
  • 缓存预热,将热点数据加载到多级缓存中。预热也是很关键的,尤其是突发大流量时。
  • 优化代码算法逻辑,降低算法复杂度,降低逻辑占用时间。
  • 锁优化。
  • 最后,当然还要根据自己的业务场景,分析其他占用时间的可优化点。

高可用的解决方案

提升系统可用性的总策略是尽可能的让系统稳定的处理了业务。

提升系统高可用的方案一般有。

  • 集群部署,当一个机器故障,还有其他机器可以提供服务。
  • 故障转移,即当发生故障时,要制定容错策略。如 Dubbo 中的失败重试机制。
  • 接口层面要做合理的超时设计、幂等设计等。
  • 降级,当大流量来了,要根据业务特点,保证核心业务的稳定,可以适当降级非核心业务。
  • 限流,可以从入口接口层面制定限流策略,防止大流量一下击垮系统。
  • 监控报警,要做完善的监控报警系统,如机器指标、服务指标、业务指标等方面的监控。
  • 故障演练,在条件允许的情况下,要定时做故障演练,来检验系统的健壮性。这一块可以参考 “混沌工程”。

高伸缩性的解决方案

要提高系统的伸缩性,一般都要从架构设计入手。其最大的原则是要解决影响扩容效果的点(如分布式锁)。

  • 合理的分层,如网关层、业务逻辑层、基础服务层等,这样每一层都可以根据自己的系统流量特点,来制定扩容和缩容方案。
  • 数据库拆分,可以根据业务先进行垂直拆分,再根据业务内的数据结构进行分库分表。
  • 根据业务合理的拆分服务,如订单服务、支付服务、会员服务等。

写在最后

最后,我想说的是,大型高并发系统,是一个庞大且复杂的系统,要实现一个高并发系统,还离不开众多的基础设施的建设,如全链路压测机制、分布式trace、流控系统、服务治理、监控系统等等。

本文对于高并发系统的解决方案着重围绕三大目标展开,当然要实现这些目标,涉及面非常的广,这里我只是罗列了常见的解决方案,欢迎感兴趣的朋友们多多补充。

版权声明:本文于 2022 年 7 月 19 号发表于掘金平台,未经作者同意,谢绝转载!

我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿

猜你喜欢

转载自juejin.im/post/7122096564260044814
今日推荐