引
当你登陆到一台可能有性能问题的服务器上,你会/应该做什么?又该如何去进行初步的性能分析?
本文要介绍的USE
方法(USE Method
)则是一种分析性能问题的方法,通过执行一系列的检查项命令,来帮助我们识别资源瓶颈和系统错误。就像飞行手册中的紧急检查表一样,它的目的是简单、直接、完整和快速。
USE方法
USE
方法的USE
是utilization
、saturation
和error
的首字母的加和,意思是:「对于每一个资源,检查使用率、饱和程度和错误情况。」它的目的是今早的进行性能检查,并发现系统瓶颈。
我们首先明确一些概念:
- 资源(
resource
):服务器上的物理资源,如CPU
、磁盘等; - 使用率(
utilization
):资源进行服务工作的平均时间; - 饱和程度(
saturation
):资源无法提供额外的工作(通常表现为排队); - 错误情况(
errors
):错误事件发生的情况;
对于使用率也有另一种概念就是已使用资源的比例,这种情况下100%的利用率表示没有更多的资源可以使用。
对于这些概念,我们通常有如下的一些指标:
- 使用率(
utilization
):一段时间内的百分比,例如,CPU
的使用率是90%
; - 饱和程度(
saturation
):作为队列长度,例如,“CPU 的平均运行队列长度为 4”; - 错误情况(
errors
):标量计数。例如,“此网络接口已发生五十次迟到冲突”;
资源
资源列表
在开始USE
方法前,我们首先要知道机器上的资源都有哪些:
CPU
:socket
、cores
、硬件线程(hardware threads
)Memory
:资源容量Network
:网络接口- 存储设备:
I/O
、容量 - 控制器:存储器、网卡
- 连接情况(
Interconnects
):CPUs
、内存、I/O
有些资源是两种类型的资源:存储设备是服务请求资源(I/O
),也是容量资源。这两种类型都可能成为系统的瓶颈。请求资源可以被定义成一个排队系统,请求到来先排队,然后服务。
这里我们忽略了像硬件缓存这样的物理组件,因为USE
方法对于在高利用率或饱和情况下性能下降、导致瓶颈的资源最有效,cache
可以帮助我们在高使用率情况下提升性能。在排除系统瓶颈后,可以在 USE 方法之后检查缓存命中率和其他性能属性。
功能框架图
另一种获取资源列表的方法是查找或者绘制系统的功能框架图。我们不仅能从中知道资源情况,还可以知道数据的流动情况。例如如下就是Sun Fire V480
对应的功能框架图:
Sun Fire V480
通过这样的功能框架图,我们可以从整体上理解机器的运行情况。在确定各种总线的利用率时,我们可以在功能图上标注每条总线的最大带宽。通过这种方式我们可以得到一个图标,从而可能可以提前发现系统的瓶颈在哪里。
连接情况(Interconnects)
CPU
、内存和I/O
之间的连接经常会被忽略。幸运的是,这通常不是系统瓶颈;不幸的是,如果这是系统瓶颈,我们也很难去进行优化。
使用率低是否意味着不饱和?
如果在长时间内的使用率很低,但是使用率偶尔会非常高的话,也是可能出现饱和情况的。所以使用率低并不意味着不饱和。
此外在一些场景里,就是一些资源饱和了导致了其他资源的使用率低。例如在一个高I/O
场景中,如果磁盘饱和,CPU
可能就会出现饥饿的情况。
云计算环境的资源
在云计算环境中,租户使用的系统资源可能是会被限制的。因此在这种情况下,我们需要考虑租户的资源限制,而不是考虑整体的情况。
指标
给定资源,我们需要考虑三种监控类别:使用率、饱和程度和错误情况。
下面是一些例子,读者可以先尝试填一填,看看能用什么指标来描述这些属性:
Metrics
注意:这些指标要么是每个时间间隔的平均值,要么是计数。举例来说,CPU
的使用率我们可以用top
等工具得到CPU
使用率数据,那么我们可以用什么来表示CPU
的饱和情况呢?
下图就是补充完整后的列表:
Metrics
可以看出,对于使用率来说,一般我们会用使用率、资源容量这样的指标来进行量化;而对于饱和程度,我们往往会通过饱和以后的动作来进行量化,例如CPU
饱和就会出现排队现象,内存饱和就会出现换页的情况。
更难的指标
下面我们思考一些更难量化的指标:
Harder Metrics
读者可以尝试做更多的思考,例如我们该如何判断CPU
出现错误了呢?CPU
出现错误的表征是什么呢?我们又如何量化这些表征呢?这里的结果我们放在文末揭晓。也许这里面最简单的就是Memory
错误了,快想一想,那个经常出现的报错是什么。
通过对资源的使用率、饱和程度和错误情况做检查,我们会得到大约三十个左右的指标列表,有一些指标我们很容易得到,例如CPU
的使用率,而有一些则没有那么容易获取。幸运的是,最常见的问题都是很容易发现的,我们借助已有的工具就可以快速的发现大部分的问题。
对于检查项,Gregg编写了一份针对不同系统的检查项列表,在附录可以找到。
实践
读取操作系统上所有在检查表上的指标可能会非常耗时,我们可能只有时间检查一部分的指标:CPU
、内存容量、存储容量、网络接口等。这也是一次非常好的尝试,因为我们借助USE
方法将未知的未知变成了已知的未知。当我们需要找出性能瓶颈时,我们就有了一份检查项列表,可以用来帮助我们进行分析。
软件资源
对于一些软件资源,我们也可以用类似的方法来进行探索,例如:
- 互斥锁(
mutex lock
):使用率可以定义为持有锁的时间;排队等待锁的线程饱和; - 线程池(
thread pool
):利用率可以定义为线程忙于处理工作的时间;等待线程池服务的请求数量的饱和度; - 文件描述符容量(
file descriptor capacity)
:如上
建议的解释
USE
方法帮助我们搞清楚该获取哪些指标。在了解到如何从操作系统获取这些指标后,我们需要去解释这些值。对于一些值,它的解释是显而易见的;而对于一些纸,我们可能需要基于具体的工作负载和期望来进行解释。
下面是指标的一些解释建议例子:
- 使用率:百分百使用率通常是性能瓶颈的信号,我们需要通过饱和程度来进行二次确认。由于如下的一些原因,高的使用率(例如大于
70%
)可能是问题:- 在相对较长的时间里测量使用率时,高的使用率可能会隐藏短时间内百分百利用率的突刺情况;
- 某些系统资源如磁盘在操作期间是不能被中断的,一旦利用率超过
70%
,排队延迟就会变得更加明显和频繁;
- 饱和情况:任何程度的饱和都可能成为问题。我们可以通过等待队列的长度或等待队列所花费的时间来衡量;
- 错误情况:非零错误计数器值得研究,特别是如果它们在性能较差的情况下仍在增加
使用策略
我们可以基于如下的流程图来进行USE
方法的实践:
USE method
在检测使用率和饱和程度之前检测错误情况是一个小的优化,因为错误情况往往比较好找到且比较重要。USE
方法能够发现可能成为系统瓶颈的问题,但是不幸的是,系统可能同时存在多个问题,我们发现的问题可能并不是问题本身,我们需要基于发现的问题去做更多的发散。更进一步的分析包括工作负载表征和下钻分析,在完成了这些操作后,我们就应该有证据证明我们应该调整负载还是调整资源本身了。
总结
USE
方法是一种简单的策略,我们可以用它来进行系统运行情况的完整检查,并识别常见的瓶颈和错误。它可以在性能分析的早期进行并快速识别问题领域,在此基础之上我们使用其他的方法做更进一步的分析。USE
方法的优点在于速度和可见性:通过考虑所有资源,我们不太容易漏掉检查项;缺点在于其只能发现某些类型的问题(瓶颈和错误)。因此我们只能将其作为整个性能优化工具箱中的一个工具。
作为性能优化分析的起点,USE
方法从使用率、饱和程度和错误情况对资源做了检查,其核心在于让我们对系统有一个直观的了解和认识,而不是一上来就使用一些工具进行漫无目的的抓取。
参考资料
- USE Method(https://www.brendangregg.com/usemethod.html)
- Rosetta Stone of Performance Checklists(https://www.brendangregg.com/USEmethod/use-rosetta.html)
附录
更难的指标
总体的思路还是秉持如果出现问题,问题的结果或者说可量化的现象是什么去思考。例如最平常的OOM
,就可以认为是Memory
出现错误的表征和量化指标。
Harder Metrics
检查项列表
Gregg
在Rosetta Stone of Performance Checklists给出了多个操作系统的检查项列表,读者可以自行尝试:
Checklists - 部分