本书作者起初以为仅靠研究命令行工具和指标就能提高性能。他认为这样不对。他从头到尾读了一遍手册,看懂了缺页故障、上下文切换和其他各种系统指标的定义,但不知道如何处理它们:如何从发现信号到找到解决方案。
他注意到,每当出现性能问题时,高级系统管理员都有自己的思维过程,通过工具和指标迅速找到根本原因。他们知道那些指标是重要的,什么时候会指向一个问题,以及如何使用它们来缩小调查范围。
从那时起,作者开始收集、记录、分享和开发我自己的性能优化方法。
2.1 术语
IOPS:每秒发生的输入/输出操作的次数,是数据传输率的一种度量方法,对于磁盘的读写,IOPS指的是每秒读和写的次数。
吞吐量:评价工作执行的速度,尤其是数据传输方面,这个术语用于描述数据传输的速度(字节/秒或比特/秒)。在某些情况下(如数据库),吞吐量指的是操作的速度(每秒操作数或每秒业务数)。
响应时间:完成一次操作的时间。包括用于等待和服务时间,也包括用来返回结果的时间。
使用率:对于服务所请求的资源,使用率描述在给定的时间区间内资源的繁忙程度。对于提供存储的资源来说,使用率指的是所消耗的存储容量(例如内存使用率)。
饱和度:指的是某一资源无法提供服务的工作的排队程度。
瓶颈:在系统性能里,瓶颈指的是限制系统性能的那个资源。分辨和移除系统瓶颈是提高系统性能的一项重要工作。
工作负载:系统的输入或者对系统所施加的负载叫做工作负载。对于数据库来说,工作负载就是客户端发出的数据库请求和命令。
缓存:用于复制或者缓冲一定量数据的高速存储区域。目的是为了避免对较慢的存储层级的直接访问,从而提高性能。出于经济考虑,缓存区的容量要比慢一级的存储容量小。
2.2 模型
2.2.1 受测系统
扰动是会影响结果的,包括定时执行的系统活动、系统中的其他用户以及其他工作负载导致的结果。扰动的来源可能不是很清楚,需要细致地进行系统性能研究才能加以确定。
现代环境中的另一个困难是系统可能由若干个网络化的组件组成,他们都用于处理工作负载,包括负载均衡、Web服务器、数据库服务器、应用程序服务器,以及存储系统。
2.2.2 排队系统
某些组件和资源可以模型化为排队系统,这样在不同情况下它们的性能就可以根据模型被预测出来。磁盘通常被模型化为排队系统,排队系统可以预测响应时间在负载下如何退化的。
2.3 概念
2.3.1 延时
某些环境,延时是被唯一关注的性能焦点。单说延时容易造成混淆,因此在使用时最好加上限定词解释它测量的是什么,如是请求延时还是TCP连接延时。
性能问题可以用延时来进行量化和评级,因为是用相同的单位来表达时间。通过考量所能减少或移除的延时,预计的加速也可以被计算出来。
如果可能,其他的指标也会转化为延时或时间。
2.3.2 时间量级
可以对时间进行量化的比较,同时最好对时间和各种来源的延时的合理预期有本能的认知。系统各组件的操作的时间量级差别巨大。对于一个3.5GHz的CPU而言,系统的各种延时的时间量级如下:
事件 | 延时 | 相对时间比例 |
1个CPU周期 | 0.3ns | 1s |
L1缓存访问 | 0.9ns | 3s |
L2缓存访问 | 3ns | 10s |
L3缓存访问 | 10ns | 33s |
主存访问 | 100ns | 6分 |
固态硬盘 | 10~100us | 9~90小时u |
旋转磁盘 | 1~10ms | 1~12月 |
互联网:从旧金山到纽约 | 40ms | 4年 |
互联网:从旧金山到英国 | 81ms | 8年 |
轻量化硬件虚拟化重启 | 100ms | 11年 |
互联网:从旧金山到澳大利亚 | 183ms | 19年 |
操作系统虚拟化重启 | <1s | 105年 |
基于TCP定时器的重传 | 1~3s | 105~317年 |
SCSI命令超时 | 30s | 3千年 |
硬件虚拟化系统重启 | 40s | 4千年 |
物理系统重启 | 5m | 32千年 |
2.3.3 权衡
许多IT项目选择了及时和成本低,留下了性能问题在以后解决。例如,选择了非最优的存储架构或者使用的编程语言或操作系统缺乏完善的性能分析工具。
常见的性能调优的权衡是在CPU和内存之间,因为内存能用于缓存数据结果,降低CPU的使用率。在CPU资源充足时候,可以压缩数据来降低内存的使用。
2.3.4 调优的影响
性能调优实施在越靠近工作执行的地方效果最显著。调优示例:
层级 | 调优对象 |
应用程序 | 应用程序逻辑、请求队列大小、执行的数据库请求 |
数据库 | 数据库表的布局、索引、缓冲 |
系统调用 | 内存映射或读写、同步或异步IO标志 |
文件系统 | 记录尺寸、缓存尺寸、文件系统可调参数、日志 |
存储 | RAID级别、磁盘类型和数目、存储可调参数 |
对应用程序层级进行调优,可能通过消除或减少数据库查询获得很大的性能提升。在存储设备层级进行调优,可以精简或提高存储IO,但是性能提升的重要部分在更高层级的操作系统栈代码,所以对存储设备层级的调优对应用程序的性能的提升有限,是百分比量级的。
在应用程序级别寻求性能的巨大提升,还有一个理由。如今许多环境都致力于特性和功能的快速部署,按每周或每天将软件的变更推入生产环境。因此,应用程序的开发和测试倾向于关注正确性,在部署前留个性能测量和优化的时间很少甚至没有。
数据库查询缓慢最好从其所花费的CPU时间、文件系统和所执行的磁盘IO方面来考察。
操作系统的调优以及从操作系统层面观测问题这两点容易忽略。谨记一点,操作系统的性能分析能辨别出来的不仅是操作系统层级的问题,还有应用程序层级的问题。
2.3.5 合适的层级
性能技术投入的投资回报率。系统性能不仅仅是成本问题,还关系到终端用户的体验。在做性能分析时候,合适的程度是判断何时停止分析的关键。
2.3.6 何时停止分析
性能分析的一个挑战是如何知道何时停止。以下3种情况,考虑停止分析:
1. 当你已经解释了大部分性能问题的时候。
2. 当潜在的投资回报率低于分析的成本的时候。
3. 当其他地方有更大的投资回报率的时候。
2.3.7 性能推荐的时间点
环境的性能特性会随着时间改变,更多的用户、新的硬件、升级的软件或固件都是变化的因素。
性能推荐,尤其是可调优的参数值,仅仅在一段特定时间内有效。
当改变可调整参数时候,把它们存储在一个有详细历史记录的版本控制系统中很有帮助。
2.3.8 负载与架构
应用程序性能差可能是因为软件配置和硬件的问题,也就是它的架构和实现问题。另外,应用程序性能差还可能是由于有太多负载,而导致了排队和长延时。
如果对架构的分析显示只是工作任务在排队,处理任务没有任何问题,那么可能就是施加的负载太多了。
2.3.9 扩展性
负载增加下的系统所展现的性能称为扩展性。在前期,扩展是线性变化的,当达到某一点,对资源的争夺开始影响性能。吞吐量曲线就会随着资源争夺的加剧偏离了线性扩展。最终,争夺加剧的开销和一致性导致完成的工作量变少,吞吐量下降。
偏离线性扩展可能发生在组件接近或达到100%使用率的时候--饱和点。这时排队频繁比较明显。当CPU接近100%使用率时,由于CPU调度延时增加,性能开始下降。在性能达到峰值后,在100%使用率时,吞吐量已经开始随着更多线程的增加而下降,导致更多的上下文切换,这会消耗CPU资源,导致实际完成的任务变少。
当系统开始换页来补充内存的时候,导致性能“快速”下降的原因可能是内存的负载。导致性能“慢速”下降的原因则可能是CPU的负载。
还有一个导致性能“快速”下降的因素是磁盘IO。随着负载(和磁盘使用率)的增加,IO可能会排队。
如果资源不可用,应用程序开始返回错误,响应时间是直线变化的,而不是将工作任务排队。
2.3.10 指标
性能指标是由系统、应用程序,或者其他工具选定的统计数据,用于测量感兴趣的活动。性能指标用于性能分析和监测。
常见的系统性能指标如下:
吞吐量:每秒的数据量或操作量。
IOPS:每秒的IO操作数。
使用率:资源的繁忙程度,以百分比表示。
延时:操作时间,以平均数或百分数表示。
吞吐量的使用取决于上下文环境。数据库吞吐量吞吐量通常用来度量每秒查询或请求的数目(操作量)。网络吞吐量度量的是每秒传输的比特数或字节数。
IIOPS度量是吞吐量,但只针对IO操作(读取和写入)。
开销:性能指标不是免费的,在某些时候,会消耗一些CPU周期来收集和保存指标信息,这就是开销,被称为观察者效应。
问题:指标可能会是混淆的、复杂的、不可靠的、不精确的、甚至是错误的(由bug导致)。有时某一版本上对的指标,由于没有得到及时更新,而无法反映新的代码和代码路径。
2.3.11 使用率
使用率经常用于操作系统描述设备的使用情况,例如CPU和磁盘设备。使用率是基于时间的,或者基于容量的。
基于时间:使用排队理论作正式定义。服务器或资源繁忙时间的均值。使用率=T时间内系统繁忙时间/观测周期T。
使用率说明组件的忙碌程度:当一个组件的使用率达到100%,资源发生竞争时性能会有严重的下降。某些组件能并行地为多个操作提供服务。对于这些组件,在100%使用率的情况下,性能下降的幅度可能不会太大,因为他们仍能接受更多的工作。
基于容量的:系统或组件都能够提供一定的吞吐量。不论性能处于何种级别,系统或组件都工作在其容量的某一比例上。这个比例就称为使用率。
注意100%忙碌不意味着100%的容量使用。
2.3.12 饱和度
随着工作量增加而对资源的请求超过资源所能处理的程度叫做饱和度。饱和度发生在100%使用率(基于容量),这时多出的工作无法被处理,开始排队。
使用率超过100%之后,时间会花在等待上,所以任何程度的饱和度都是性能问题。对于基于时间的使用率(忙碌百分比),排队和饱和度可能不发生在100%使用率时,这取决于资源处理任务的并行能力。
2.3.13 剖析
剖析profiling的本意是指对目标对象绘图用于研究和理解。在计算机性能领域,剖析通常是按照特定的时间间隔对系统的状态进行采样,然后对这些样本进行研究。不像之前IOPS和吞吐量指标,采样所能提供的对系统活动的观测比较粗糙,当然这也取决于采样率的大小。
2.3.14 缓存
一般使用多级缓存。开始是一个非常快但很小的缓存L1,后续的L2和L3逐渐增加了缓存容量和访问延时。这是一个在密度和延时之间经济上的权衡。缓存的级数和大小的选择以CPU芯片内可用空间为准,确保达到最优的性能。
一个了解缓存性能的重要指标是每个缓存的命中率--所需数据在缓存中被找到的次数与总访问次数的比例。
命中率 = 命中次数 / (命中次数 + 失效次数)
命中率越高越好,更高的命中率意味着更多的数据能成功地从较快的介质中访问获得。随着缓存命中率的提升,预期的性能提升曲线是非线性的。98%和99%之间的性能差异要比10%和11%之间性能差异大得多。由于缓存命中和失效之间的速度差异(两个存储层级),导致了这是一条非线性曲线。两个存储层级速度差异越大,曲线越陡峭。
了解缓存性能的另一个指标是缓存的失效率,指的是每秒缓存失效的次数。这与每次缓存失效对性能的影响是成比例的。
在不同算法来解决同一个任务时候,不仅要看命中率,还要看访问次数。这样才能比较最终的失效次数。运行时间 = 命中率 * 平均命中延时 + 失效率 * 平均失效延时。
缓存管理算法和策略决定了在有限的缓存空间内存放那些数据。最近最少使用算法,最近最常使用算法等等。
缓存的热、冷和温:
冷:冷缓存是空的,或者填充的都是无用的数据。冷缓存命中率为0.
热:热缓存填充的都是常用的数据,并有着很高的命中率,例如,超过90%。
温:温缓存填充了有用的数据,但是命中率还没达到预想的高度。
热度:提高缓存的热度的目的就是提高缓存的命中率。
比如12GB的drama作为文件系统的缓存,600GB的闪存作为二级缓存,物理磁盘作为存储器。磁盘每秒读操作约有2000次,按照8KB的IO大小,缓存变温的速度仅有16MB/s,需要2小时让DRAM变温,需要10小时让闪存变温。
2.3.15已知的未知
已知的已知、已知的未知、未知的未知在性能领域是很重要的概念。
已知的已知:有些东西你知道。你知道你应该检查的性能指标,你也知道它的当前值。比如,你知道你应该检查CPU使用率,而且你也知道当前均值为10%。
已知的未知:有些东西你知道你不知道。你知道可以检查一个指标或者判断一个子系统是否存在,但是你还没去做。举例,你知道能用剖析检查是什么导致CPU忙碌,但你还没去做这个事情。
未知的未知:有些东西你不知道。举例,你可能不知道设备中断可以消耗大量CPU资源,因此你对此并不做检查。
2.4 视角
性能分析常用的两个视角:工作负载分析和资源分析,可以分别对应理解为对系统软件栈自上而下和自底向上的分析。
2.4.1 资源分析
资源分析对系统资源的分析为起点,涉及的系统资源有:CPU、内存、磁盘、网卡、总线以及它们之间的互联。
操作如下:
1. 性能问题研究:看是否是某特定类型资源的责任。
2. 容量规划:为设计新系统提供信息,或者对系统资源何时会耗尽做预测。
这个视角着重使用率的分析,判断资源是否已经处于极限或者接近极限。适合资源分析的指标如下:
1. IOPS;
2. 吞吐量;
3. 使用率;
4. 饱和度;
这些指标度量了在给定负载下资源所作的事情,显示资源的使用程度乃至饱和的程度。其他类型的指标,包括延时,也会被用来度量资源对于给定工作负载的响应情况。
2.4.2 工作负载分析
工作负载分析:所施加的工作负载和应用程序是如何响应的。
工作负载分析的对象如下:
1. 请求:所施加的工作负载;
2. 延时:应用程序的响应时间;
3. 完成度:查找错误;
工作负载分析的任务包括辨别并确认问题:通过查找超过可接受阈值的延时,来定位延时的原因(向下钻取分析),并确认在修复之后延时会有改善。需要注意的是,分析的起点是应用程序。为了研究延时,通常需要深入应用程序、程序使用的库,乃至操作系统(内核)。
一些系统问题可以研究事件完成的特征来识别,比如,错误码。虽然请求完成得很迅速,但返回的错误码会导致该请求被重试,从而增加了延时。
适合工作负载分析的指标如下(度量了请求量的大小和在其之下系统表现出的性能):
1. 吞吐量(每秒业务处理量);
2. 延时。
2.5 方法
当面对性能低下且复杂的系统环境的时候,第一个挑战是要知道从那里开始分析和如何进行分析。性能问题可能出自任何地方,包括软件、硬件、数据路径上的任何组件。方法可以帮助你了解这些复杂的系统,告诉你从那里开始分析,并提供有效的可以遵循的程序。
2.5.5 问题陈述法
明确如何陈述问题支持人员反映问题时的例行工作。询问如下:
1. 是什么让你认为存在性能问题?
2. 系统之前运行得好么?
3. 最近有什么改动?软件、硬件、负载?
4. 问题能用延时或者运行时间来表述么?
5. 问题影响其他的人和应用程序吗(或者仅仅影响你)?
6. 环境时什么样的?用了那些软件和硬件?是什么版本?是怎么样配置的?
询问这些问题并得到相应的回答通常会立即指向一个根源和解决方案。
2.5.6 科学法
科学法是通过假设和测试来研究未知的问题的。总结如下:
1. 问题;
2. 假设;
3. 预测;
4. 测试;
5. 分析;
问题就是性能问题的陈述。从这点你可以假设性能不佳的原因可能是什么。然后开始测试,可以是观测性的也可以是实验性的,看看基于假设的预测是否正确。最后分析收集的测试数据。
示例(观测性):
1. 问题:什么导致了数据库查询很慢?
2. 假设:其他云计算租户在执行磁盘IO,与数据库的磁盘IO在竞争(通过文件系统)。
3. 预测:如果得到在数据库查询过程中的文件系统IO延时,可以看出文件系统对于查询很慢是有责任的。
4. 测试:跟踪数据库文件系统延时,发现在文件系统上等待的时间在整个查询查询的比例小于5%。
5. 分析:文件系统和磁盘对查询速度慢没有责任。
示例(实验性):
1. 问题:为什么HTTP请求从主机A到主机C要比从主机B到主机C要长?
2. 假设:主机A和主机B在不同的数据中心。
3. 预测:把主机A移动到与主机B一样的数据中心将修复这个问题。
4. 测试:移动主机A并测试性能。
5. 分析:性能得到修复---与之前假设一致。
如果问题没有得到解决,在开始新的假设之前,要恢复试验之前的变动(对于此例,就是把主机A移回去)。如果一次改变多个因素,将很难识别导致问题的原因。
示例(实验性):
1. 问题:为什么随着文件系统缓存尺寸变大,文件系统的性能会下降?
2. 假设:大的缓存存放更多的记录,相较于小的缓存,需要花更多的计算来管理。
3. 预测:把记录的大小逐步变小,使得存放相同大小的数据需要更多的记录,性能会逐渐变差。
4. 测试:用逐渐变小的记录尺寸,试验同样的工作负载。
5. 分析:结果绘图后与预测一致。向下钻探分析现在可以研究缓存管理的程序。
2.5.9 USE方法
USE方法:对于所有的资源,查看它的使用率、饱和度和错误。
资源:
所有服务器的物理元器件(CPU、总线......)。某些软件资源也能被算在内,提供有用的指标。
使用率:
在规定的时间间隔内,资源用于服务工作的时间百分比。虽然资源繁忙,但是资源还有能力接受更多的工作,不能接受更多工作的程度被视为饱和度。
饱和度:
资源不能再服务更多额外工作的程度,通常有等待队列。有时也被称为压力。
错误:
错误事件的个数。
对于某些资源,包括内存,使用率指的是资源所用的容量。一旦资源的容量达到100%的使用率,那它就无法接受更多的工作,资源或者对工作进行排队(饱和),或者返回错误,用USE方法也就可以予以鉴别。
错误需要被调查,因为它们会损害性能,如果故障模式是可以恢复的,错误可能难以立即被察觉。这包括操作失败重试,还有冗余设备池中的设备故障。
USE列举的系统资源可以帮助你得到一张完整的问题列表,在你寻找工具时候进行确认。
USE会将分析引导到一定数量的关键指标上,这样可以尽快地核实所有的系统资源。
过程:首先检查错误,因为错误通常可以很快解释(错误通常是客观的而不是主观的指标),在调查其他指标之前排除错误是很省时的。排在第二的是饱和度检查,因为它比使用率解释得更快:任何级别的饱和度可能是问题。
这个方法辨别出的很可能是系统瓶颈问题。不过,一个系统可能不只面临一个性能问题,因此你可能一开始就能找到问题,但所找到的问题不是你关心的那个。在根据需要返回USE方法遍历其他资源之前,每个发现用更多的方法进行排查。
指标描述:
1. 使用率:一定时间间隔内的百分比值。(例如,单个CPU运行在90%的使用率上)
2. 饱和度:等待队列的长度。(例如,CPU的平均运行队列长度是4)
3. 错误:报告出的错误数目。(例如,这块磁盘设备有50个错误)
虽然看起来有点违反直觉,但即使整体的使用率在很长一段时间都处于较低水平,一次高使用率的瞬时冲击还是能导致饱和与性能问题。
资源列表:
USE方法的第一步是要创建一张资源列表,要尽可能完整。USE方法是处理在高使用率或饱和状态下性能下降的资源的最有效的方法。一台服务器通常的资源列表如下:
CPU:插槽、核、硬件线程;
高速缓存:多级缓存;
内存:DRAM;
网络接口:以太网端口,无限带宽技术;
存储设备:磁盘,存储适配器;
加速器:GPU、TPU、FPGA等;
控制器:存储、网络;
互联:CPU、内存、IO;
每个组件通常作为一类资源类型。例如,内存是一种容量资源,网络接口是一种IO资源(IOPS或吞吐量)。有些组件是多种资源类型,例如,存储设备即是IO资源,也是容量资源。这是需要考虑到所有的类型都能够造成性能瓶颈,同时,也要知道IO资源可以进一步被当作排队系统来研究,排队系统将请求排队并为其服务。
原理框图:
另一种便利所有资源的方法是找到或者画一张系统的原理框图,此图显示了组件的关系,对寻找数据流中的瓶颈是很有帮助的。
CPU、内存、IO互联和总线常常被忽视。所幸的是,它们不是系统的常见瓶颈。因为这些组件本身就设计有超过吞吐量的余量。
指标:
一旦有了资源列表,就可以考虑三类指标:使用率、饱和度,以及错误。
资源 | 类型 | 指标 |
CPU | 使用率 | CPU使用率(单CPU使用率或系统级均值) |
CPU | 饱和度 | 运行队列长度、调度器延时、CPU压力 |
CPU | 错误 | 机器检查异常、CPU 缓存ECC错误 |
内存 | 使用率 | 可用空闲内存(系统级) |
内存 | 饱和度 | 交换分区、页面扫描、内存缺失事件、内存压力 |
内存 | 错误 | 失败的malloc函数 |
网络接口 | 使用率 | 接收吞吐量/最大带宽、发送吞吐量/最大带宽 |
存储设备IO | 使用率 | 设备繁忙百分比 |
存储设备IO | 饱和度 | 等待队列长度、IO压力 |
存储设备IO | 错误 | 设备错误(硬错误、软错误) |
网络 | 饱和度 | 网络接口或操作系统错误(linux的overrun) |
存储控制器 | 使用率 | 针对当前活动可能有最大IOPS或吞吐量可供检查 |
CPU互联 | 使用率 | 每个端口的吞吐量/最大带宽(CPU性能计数器) |
内存互联 | 饱和度 | 内存停滞周期数,偏高的平均指令周期数(CPU性能计数器) |
IO互联 | 使用率 | 总线吞吐量/最大带宽 |
上述某些指标可能用操作系统的标准工具是无法获得的,需要使用动态跟踪或者用到CPU性能计数工具。
软件资源:本书是指小的软件组件,而不是整个应用程序。
互斥锁:锁被持有的时间是使用率,饱和度指的是有线程队列在等待锁。
线程池:线程忙于处理工作的时间是使用率,饱和度指的是等待线程池服务的请求数目。
进程/线程容量:系统的进程或线程的总数是有上限的,当前的使用数目是使用率,等待分配u的数目是饱和度,错误是分配次数。
文件描述符容量:同进程/线程容量一样。
使用建议:
使用率:100%的使用率通常是瓶颈的信号(检查饱和度并确认其影响)。使用率超过60%可能会是问题。基于以下理由:
1. 时间间隔的均值,可能掩盖了100%使用率的短期爆发。
2. 一些资源,诸如硬盘,通常在操作期间是不能被中断的,即使是为优先级较高的工作让路。
饱和度:任何程度的饱和都是问题。饱和度可以用排队长度或者排队所花的时间来度量。
错误:错误都是值得研究的,尤其是随着错误增加性能会变差的那些错误。
缩小研究范围能帮你快速地将精力集中在出问题的地方,判断其不是某一个资源的问题,这是一个排除的过程。
资源控制:
在云计算和容器环境中,软件资源控制在于限制或给分享系统的多个租户设定阈值。资源控制会设定内存、CPU、磁盘IO及网络IO的限制。
2.5.12 向下钻取分析
向下钻取分析开始于检查高层次的问题,然后依据之前的发现缩小关注的范围,忽视那些无关的部分,更深入发掘那些相关的部分。整个过程会探究到软件栈较深的领域,如果需要,甚至还可以到硬件层,以求找到问题的根源。
以下是系统性能的三阶段向下钻取分析方法:
1. 监测:用于记录高级别的统计数据,如果问题出现,予以辨别和报警;
2. 识别:对于给定问题,缩小研究的范围,找到可能的瓶颈。
3. 分析:对特定的系统部分作进一步的检查,找到问题根源并量化问题。
现代监测系统使用导出器:在每个系统上运行软件代理,用来收集和发布指标。产生的数据由监测系统记录,并由前端GUI进行可视化。这可以揭示出在短期内使用命令行工具可能被忽略的长期模式。许多监测解决方案能在怀疑有问题的时候发出警报,让分析进入下一阶段。
2.5.13 延时分析
延时分析检查完成一项操作所用的时间,然后把时间再分成小的时间段,接着对有着最大延时再次作划分,最后定位并量化问题的根本原因。与向下钻取分析相同,延时分析也会深入软件栈的各层来找到延时问题的原因。
分析可以从所施加的工作负载开始,检查工作负载是如何在应用程序中被处理的,然后深入操作系统的库、系统调用、内核以及设备驱动。
据个例子,SQL的请求延时分析可能涉及下列问题的回答:
1. 存在请求延时问题马?(是的)
2. 查询时间主要是在on-CPU还是在off-CPU等待?(off-CPU)
3. 没花在CPU上的时间在等待什么?(文件系统IO)
4. 文件系统的IO时间是花在磁盘IO上还是锁竞争上?(磁盘IO)
5. 磁盘IO时间主要用在排队还是服务IO?(服务)
6. 磁盘服务时间主要是IO初始化还是数据传输?(数据传输)
对于这个问题,每一步所提出的问题都将延时计划分成两部分,然后继续分析那个较大可能的部分:延时的二分搜索。
2.5.17 静态性能调优
静态性能调优着重处理的架构配置的问题。其他方法着重处理的负载施加后的性能:动态性能。静态性能分析是在系统空闲没有施加负载的时候执行的。
做性能分析和调优,要对系统的所有组件逐一确认下列问题:
该组件是否合理的?(过时的、功率不足的,等等)
配置是针对预期的工作负载设定的吗?
组件的自动配置对于预期的工作负载是最优的吗?
有组件出现错误吗?是在降级状态吗?
下面是一些静态性能调优中可能发现的问题:
网络接口协商:选择1GB/s而不是10GB/s;
建立RAID池失败;
使用的操作系统、应用程序或固件是旧的版本;
文件系统几乎满了(会导致性能问题);
文件系统记录的尺寸和工作负载IO的尺寸不一致;
应用程序在运行时意外开启了高成本的调试模式;
服务器意外被配置了网络路由(开启了IP转发);
服务器使用的资源,诸如认证,来自远端的数据中心,而不是本地的。
2.5.18 缓存调优
介绍的各级缓存的通用调优策略:
1. 尽量将缓存放在栈的顶端,靠近工作开展的地方,以降低缓存命中的操作开销。这个地方也应该有更多可用的元数据,可以用来改进缓存的保留策略。
2. 确认缓存开启并确定在工作。
3. 确定缓存的命中/失效比例和失效率。
4. 如果缓存的大小是动态的,确认它的当前尺寸;
5. 针对工作负载调整缓存。这项工作依赖缓存的可调参数。
6. 针对缓存调整负载。包括减少对缓存不必要的消耗,可以释放更多的空间来给目标工作负载使用。
要小心二次缓存--比如,消耗主存的两个不同的缓存块,或把相同的数据缓存了两次。还有要考虑每一层缓存调优的整体性能收益。
2.5.19 微基准测试
微基准测试测量的是简单的人造工作负载的性能。宏观基准测试旨在测量真实世界和自然的工作负载。宏观基准测试是通过运行工作负载仿真来进行的,执行和理解的复杂度高。微基准测试由于涉及的因素较少,所以在执行和理解上会较为简单。
可以用微基准测试工具来施加工作负载并度量性能。或者用负载生成器工具来产生负载,其他工具进行性能测量。
微基准测试通常在目标系统上执行会尽可能快,测量完成大量的上述这类操作所用的时间,然后计算均值(平均时间=运行时间/操作次数)。
2.5.20 性能箴言
1. 不要做;消除不必要的工作
2. 只做一次;缓存
3. 做少点;将刷新、轮询或更新的频率调低;
4. 稍后在做;写回缓存;
5. 在不注意的时候做;安排工作或在非工作时间进行;
6. 同时做;从单线程切换到多线程
7. 做的更便宜点;购买更快的硬件。
2.6 建模
建模用途之一是可扩展分析:研究当负载或者资源扩展时性能会如何变化。资源可以是硬件,如CPU,也可以是软件,如进程或者线程。
对生产系统的观测和实验性测试,以及建模,选二者可以让性能研究更为透彻:分析建模和仿真,或者仿真和测量。
如果是对一个现有系统做分析,可以从测量开始:归纳工作负载特征和测量性能。如果系统没有生产环境或者要测试的工作负载在生产环境不可见,实验性分析,可以用工作负载仿真做测试。分析建模可基于测试和仿真的结果,对性能进行预测。
可扩展性分析可以揭示性能由于资源限制停止线性增长的点,即拐点。找到这些点是否存在,若存在,在那里,这对研究阻碍系统扩展性的性能问题有指导意义,将帮助我们在碰到这些诶问题之前就能将它们修复。
2.6.2 可视化识别:
对于每一条曲线,X轴是扩展的维度,Y轴是相应的性能(吞吐量、每秒事务数,等等)。曲线类型如下:
线性扩展:性能随着资源的扩展成比例增加。这种情况并非永远持续,但这可能是其他扩展情况的早期阶段。
竞争:架构的某些组件是共享的,而且只能串行使用,对这些资源的竞争会减少扩展的收益。
一致性:由于要维持数据一致性,传播数据变化的代价超过扩展带来的好处。
拐点:某个因素碰到了扩展的制约点,从而改变了扩展曲线。
扩展上限:到达了一个硬性的极限。该极限可能是设备瓶颈,诸如总线或互联器件达到了最大吞吐量、或者是一个软件设置的限制(系统资源控制)。
2.6.3 Amdahl定律
该定律对系统的扩展性进行了建模,所考虑的是串行构成的不能并行执行的工作负载。可以用于CPU、线程、工作负载等更多事物的扩展性性研究。Amdahl定律认为早期的扩展特性是竞争,主要是对串行资源或工作负载的竞争。公式:
C(N)=N/1+a(N-1);
C(N)表示相对容量,N是扩展维度,如CPU数目或用户负载。系数a代表串行程度,即偏离线性扩展的程度。Amdahl扩展定律的应用步骤如下:
1. 不论是观测现有系统,还是实验性地使用微基准测试,或者用负载生成器,都收集N范围内的数据。
2. 执行回归分析来判断a的值。
3. 将结果呈现出来用于分析。收集的数据点可以和预测扩展性的模型函数画在一起,看看数据和模型的差别。
2.6.4 通用扩展
Gunther博士引入一致性延时,用于描述一致性扩展的曲线,竞争的影响也包含在内。公式如下:
C(N)=N/(1+a(N-1)+bN(N-1))
b为一致性系数,当b=0时,公式就退化为Amdahl定律。
2.6.5 排队理论
排队理论是用数据方法研究队列的系统,提供了对队列长度、延时和使用率的分析方法。硬件或者软件都能建模成排队系统。多条队列系统的模型叫做队列网络。
Little定律:L=rW,系统请求的平均数目L是由平均到达率r乘以平均服务时间W得到的。
利用排队系统可以回答各种问题,如下:
1. 如果负载增加一倍,平均响应时间会怎样变化?
2. 增加一个处理器会对平均响应时间有什么影响?
3. 当负载增加1倍时,系统的90%响应时间能在100ms以下吗?
除了响应时间,排队理论还研究其他因素,包括使用率、队列长度,以及系统内的任务数目。
排队系统能用以下三个要素归纳:
1. 到达时间:描述请求到达排队系统的时间间隔,该时间可能是固定或者随机的;
2. 服务时间分布:服务所花时间,可以是确定性分布、指数分布、或者其他分布;
3. 服务中心数目:一个或多个;
对于磁盘响应工作负载的时间是固定,随着使用率的增加,磁盘的响应时间是如何变化的?根据排队理论,M/D/1的响应时间可以计算为:respond=s(2-rho)/2(1-rho)。服务时间s和使用率rho。
使用率超过60%,平均响应时间会变为2倍,超过80%,3倍。
2.7 容量规划
容量规划可以检查系统处理器负载的情况,以及系统如何随着负载的增加而扩展。研究方法包括资源极限和因素分析。
2.7.1 资源极限
对于容器来说,某个资源可以会因为碰到软件施加的限制而成为瓶颈。资源限制方法可寻找在负载之下会成为瓶颈的资源,步骤如下:
1. 测量服务器请求的频率,并监视请求频率随时间的变化;
2. 测量硬件和软件资源的使用。监视使用率随时间的变化。
3. 用资源的使用来表示服务器的请求情况;
4. 根据每个资源来推断服务器请求的极限(或用实验确定)。
开始时要识别服务器种类,以及服务器所服务的请求的种类。下一步是判断请求会消耗那些系统资源。对于未来系统,可以用微基准测试或者负载生成工具在测试环境里对要施加的请求进行仿真,同时测量资源的使用情况。
要监视的资源:
硬件:CPU使用率、内存使用、磁盘IOPS、磁盘吞吐量、磁盘使用率、网络吞吐量;
软件:虚拟内存使用情况、进程/线程/任务、文件描述符;
如果监视一段时间,可以收集到多个不同的吞吐量和使用率的数据值。可以提高估计的精确性。
2.8 统计
理解如何使用统计并且了解统计的局限性是很重要的。
2.8.1 量化性能收益
要比较问题和对问题排优先级,需要对问题和问题修复后所带来的性能的潜在提升做量化。这种事情一般用观测或者实验的方式做。
基于观测:
1. 选择可靠的指标;
2. 估计解决问题带来的性能收益;
举例如下:
观测到:应用程序请求需要10ms的时间;
观测到:其中,9ms是磁盘IO;
建议:配置应用程序将IO缓存到内存里,预期DRAM延时在10us;
估计性能收益:10ms-->1.01ms;
当要测量延时时,应确保它是作为应用程序请求的一个同步组件来被计时的。
基于实验:
1. 实施修复;
2. 用可靠的指标量化做前后对比;
举例如下:
观测到:应用程序事务平均延时10ms;
实验:增加应用程序线程数,允许更多的并发,减少排队;
观测到:应用程序事务平均延时2ms;
性能增益:10ms-->2ms;
2.9 监测
系统性能监测记录一段时间内(一个时间序列)的性能统计数据,可以对过去的记录和现在的做比较,这样能够找出基于时间的使用规律。这对容量规划、量化增长及显示峰值的和使用情况都很有用。比较过去和现在微理解性能指标的当前值提供上下文背景。
2.9.1 基于时间的规律
每小时:应用程序环境每小时都会有事情发生,诸如监测和报告任务。这些事情以每5或10分钟的合奏其执行也很常见的。
每天:每天的使用规律会和工作时间一致,如果服务是针对多个时区的,时间会拉长。
每周:和每天的规律一样,基于工作日和周末的每周的规律也可能存在;
每季度:财务报告是按季度如期完成的;
每年:负载的年度模式可以受学校的时间安排和假期影响。
2.9.2 监测产品
监测产品的典型功能包括数据存档和数据图表通过网页交互显示,还有的提供可配置的警报系统。
一部分这样的操作是通过在系统上运行代理软件收集统计数据实现的。这些代理软件运行操作系统的监测工具并解析输出文本,或者直接链接到操作系统库和接口来读取。监测产品支持一系列自定义代理,用于从特定目标导出统计数据,特定目标:网络服务器、数据库和语言运行时系统。
2.10 可视化
可视化让人们对更多的数据做检查,而且比文字更容易理解(或展示),用来确定不同指标源之间的相关性,这难以用编程实现,但是用视觉的方法来做却很简单。
图有线图、散点图、热图、表面线图,火焰图。
过去可视化很耗时,而且通常需要一个跟踪--汇报的周期。当处理紧急的性能问题时,得到性能指标的速度是很关键的。现代的可视化工具可以通过浏览器和移动设备实时地展现系统的性能。