性能概述¶
本章节包含以下内容:
1. 什么是性能¶
性能是一种指标,表明软件系统对于其及时性要求的复合程度。及时性用响应时间或者吞吐量来衡量。响应时间是对请求做出响应所需要的时间。对于单个事务可以是事务完成所需要的时间;对于用户任务,则是端对端的时间。例如,一个在线系统要求在用户按下回车键后的0.5秒内产生结果。系统吞吐量是指特定时间内能够处理的请求数量。例如,对电话交换机的要求则是每秒钟能够处理1000000次呼叫。
软件性能的及时性包括两个重要方面:响应性和可扩展性。
-
响应性是系统实现其响应时间或者吞吐量目标的能力
-
可扩展性则是系统在对其软件功能的要求增加的情况下,继续实现其响应时间或吞吐量目标的能力
注意
参考《软件性能工程》定义。
2. 理解性能指标¶
2.1. 性能指标模型¶
数据库请求响应时间: 即一个数据库请求从向数据库发起,到用户收到最后一条结果数据间的时间间隔,其大小 = CPU计算时间 + 非空闲等待时间(如IO时间、数据库锁时间)。
并发吞吐量: 即单位时间内,数据库能够处理的请求数量。该指标与前一指标的关系是:假设系统中只有一个会话,则只要该会话持续发起请求,即请求之间没有任何时间间隔,系统即可以达到其最大并发吞吐量 = 1 / 数据库请求响应时间。相应的,假设系统中有N个会话,则系统的理论上最大并发吞吐量 = N / 数据库请求响应时间——这里达到最大吞吐量的前提是:多个会话之间没有任何相互等待;系统的各种硬件资源均能够支撑这N个会话的资源需求,即最大吞吐量 = min(各类资源的处理能力 / 单个负载请求对本资源的处理能力需求)。
注意
这里的资源包括:CPU、内存、磁盘等存储设备、网络设备等硬件资源,数据库锁、应用锁等软件资源。
2.2. 数据库时间模型¶
性能优化的第一步是确定性能问题的根本原因,然后才有可能给出有效的调优建议来解决或缓解该问题。
很显然,在进行性能问题诊断时,如果我们要找出用户请求中的问题,自上而下的分析肯定是最容易理解的。根据上文中对数据库请求响应时间、并发吞吐量的指标概念及相互关系的分析,我们可以看出,在用户关心的性能指标方面,数据库请求响应时间可以作为一个基础度量,进而用以推导出吞吐量等数据。
因此,我们在数据库中引入时间模型来解决该问题。时间模型使用时间来识别数据库的各种操作对性能的量化影响。时间模型中最重要的就是数据库时间(DB TIME),DB TIME定义为在数据库中处理用户请求所花费的时间总和。这里我们给出数据库时间模型的量化公式:
数据库时间= CPU+等待时间 |
数据库调优的根本目标则是缩短数据库时间:CPU或等待时间,随之吞吐量也自然提高。
注意
数据库时间不等于响应时间,它只是用户感知到的响应时间的一部分,因为它不包含中间层(网络、中间件等)花费的时间。
3. 理解可扩展性¶
“可扩展性”一词在开发环境中被广泛使用。本节内容为应用设计者以及性能调优专家提供了一种“可扩展性”的新定义。本节包含以下内容:
-
什么是可扩展性
-
系统可扩展性
-
影响可扩展性的因素
3.1. 什么是可扩展性¶
可扩展性是当系统资源使用量成倍增加,系统处理更多负载的能力。在可扩展性系统中,如果将负载翻倍,那么使用的系统资源也应变为原来的两倍。这看上去理所应当,但由于系统内部的各种冲突,实际资源使用情况很可能超过原来的两倍。
下面列举出系统资源冲突导致可扩展性差的几个例子:
-
由于用户数量的增长,应用要求出色的并发处理能力
-
锁活动的增加
-
数据一致性负载的增加
-
操作系统负载的增加
-
由于数据规模的增大,对于数据的访问增加
-
SQL或索引的拙劣设计使得大量I/O增加
如果一个应用程序耗尽了系统资源,以至于当它的工作负载增加时不可能有更多的吞吐量,那么它就是不可扩展的。这样的应用程序必然导致不可增加的吞吐量和较差的响应时间。
下面列举出系统资源耗尽的几个例子:
-
硬件资源的耗尽
-
大规模的表扫描导致不可避免的磁盘I/O短缺
-
过多的网络请求,导致网络瓶颈
-
内存分配过低导致分页和交换
-
过多的进程和线程分配导致操作系统崩溃
这意味着应用程序设计人员必须创建一个通用的资源设计,无论用户数量和数据量如何都不会使系统资源上的负载超出其限制。
3.2. 系统可扩展性¶
可通过互联网访问的应用程序具有更复杂的性能和可扩展性要求。有些应用程序是专为互联网使用而设计和编写的,但即使是典型的后台应用程序(如总账应用程序)也可能需要部分或全部数据才能在线使用。
互联网时代应用的特点包括:
-
需要一天24小时,一年365天持续在线
-
不可预测且不精确的并发用户数
-
容量规划的困难
-
提供任何类型查询的可用性
-
多层体系结构
-
无状态中间件
-
快速增长的时间规模
-
较短的测试时间
下图显示了典型的工作负载增长曲线,需求以不断增长的速度增长。应用程序必须随着工作负载的增加而扩展,并且在添加额外的硬件时,也要提供相应支持。无论拥有多少额外的硬件资源或重新设计,设计错误都可能导致曲线达到其最大值。
应用程序的开发时间非常短,测试和评估时间有限。然而,糟糕的设计通常意味着必须稍后重新设计并重新实现系统。如果在互联网上部署一个具有已知体系结构和实现限制的应用程序,并且如果工作负载超过预期的需求,那么很有可能会失败。从商业角度来看,业绩不佳可能意味着失去客户。根据已有调查显示,如果互联网用户在7秒钟内没有得到响应,那么用户的注意力可能永远消失。
在许多情况下,重新设计系统的成本以及迁移到新实现时的相关停机成本超过了正确构建原始系统的成本。该例子的寓意很简单:设计和实现从一开始就应该考虑到可伸缩性。
3.3. 影响可扩展性的因素¶
在构建应用程序时,设计师和架构师应该尽可能地追求接近完美的可扩展性。这有时被称为线性可扩展性,即系统吞吐量与CPU数量成正比。
在实际操作中,完美的线性可扩展性实现是不可能的,因为超出了设计者的控制范围。但是,应该尽可能使应用程序的设计和实现具有可扩展性,确保当前和未来的性能目标可以通过扩展硬件组件和改进CPU技术来实现。
影响线性可扩展性的因素包括:
-
糟糕的应用程序设计、实现和配置
应用程序对可扩展性的影响最大,例如:
-
糟糕的模式设计会导致重要的SQL语句无法扩展
-
糟糕的事务设计会导致锁和序列化问题
-
连接管理不善会导致响应时间增加和系统不可靠
-
-
设计不是唯一问题。应用的物理实现同样可能是薄弱环节。
例如:
-
不良I/O策略的生产环境
-
生产环境与测试环境中生成的执行计划不同。
-
内存密集型应用程序分配大量内存而不考虑在运行时释放内存,这可能会导致内存过度使用。
-
低效率的内存使用和内存泄漏给正在运行的虚拟内存子系统带来了很大的压力。这会影响性能和可用性。
-
不正确的硬件组件大小
随着硬件价格的相对下降,硬件组件的不良容量规划问题变得不那么严重。但是,当系统的工作负载增加时,过多的容量会掩盖可伸缩性问题。
-
软件组件的限制
所有软件组件都有可扩展性和资源使用限制。这适用于应用服务器、数据库服务器和操作系统。应用程序设计不应该对软件提出超出其处理能力的要求。
-
硬件组件的限制
硬件不是完全可扩展的。大多数多处理器计算机可以在有限数量的CPU上接近线性扩展,但是在某一点之后,每个额外的CPU可以提高整体性能,但不是成比例的。可能会有一段时间,额外的CPU不会提高性能,甚至会降低性能。此行为与工作负载和操作系统设置密切相关。
-
4. 性能问题产生模型¶
性能问题是由于某些系统资源争用或耗尽的结果。当系统资源耗尽时,系统无法扩展到更高的性能级别。
而资源争用或不足的根本原因,是对资源的使用不当,或资源的处理能力已经无法满足系统的负载需要。
数据库需要的软硬件资源包括:CPU、IO、内存、网络、锁等。这些资源在达到处理能力上限的时候,通常会产生性能问题。常见的资源瓶颈现象可能包括:
-
CPU利用率接近100%
-
IO利用率接近100%
-
内存不够,开始写swap
-
网络流量达到带宽上限、网络传输存在大量错误
-
数据库内部有大量的时间在等待
注意
在进行性能调优时,DBA主要的目标是找出并优化对资源的不当使用;如果没有不当使用,则说明资源的处理能力已经无法满足系统的负载需要,此时应给出资源需求估计。
5. 如何管理性能¶
5.1. 被动性能管理¶
下面的说法中有没有听起来比较熟悉?
-
“把它构建起来,看它做的怎么样”
-
“我们以后会调整,现在没时间考虑性能”
-
“在没有能测量的东西之前,做不了任何有关性能的事”
-
“性能?那是发布版本2时要做的事情”
如果有,那么你很有可能是在被动的进行软件性能管理。被动的性能管理等待性能问题出现,然后响应式的解决,可能带来超支、不能按期交付、项目失败等潜在的风险。
有关性能问题的解决,参见 性能问题调优 。
5.2. 主动性能管理¶
主动性能管理可以预见潜在的性能问题,并在开发早期纳入有关技术。主动性能管理应该遍布开发和生产过程。