linux性能分析常用命令详解

当你登录到一台存在性能问题的Linux服务器上时,在头一分钟,你会检查什么?

我们看看Netflix的性能工程师是怎么做的。

Netflix大量使用EC2 Linux服务器,很多时候是用一些较为高层的工具做云或实例层次的分析。不过有时仍然需要登录到某个实例上,运行一些标准的Linux性能工具。

在最开始的一分钟内,可以先利用手头的标准Linux工具大致了解性能状况。借助如下10条命令(有些命令需要安装sysstat包),了解系统资源使用状况和正在运行的进程。先检查错误(errors)和饱和度(saturation),再检查资源利用率(resource utilization)。饱和度指的是负载已经超过处理能力,像请求队列的长度,等待时间等。

uptime
dmesg | tail
vmstat 1
mpstat -P ALL 1
pidstat 1
iostat -xz 1
free -m
sar -n DEV 1
sar -n TCP,ETCP 1
top

这里要提一下定位性能瓶颈的USE方法。在Brendan Gregg的《System Performance: Enterprise and the Cloud》(中译本:《性能之巅:洞悉系统、企业与云计算》)一书中有具体的描述。

如果手头有这本书的中译本,可以看一下36页:

USE方法(utilization、utilization、errors)应用于性能研究,用来识别系统瓶颈。一言以蔽之,就是:

对于所有的资源,查看它的使用率、饱和度和错误。

这些术语定义如下。

资源:所有服务器物理元器件(CPU、总线……)。某些软件资源也能算在内,提供有用的指标。
使用率:在规定的时间间隔内,资源用于服务工作的时间百分比。虽然资源繁忙,但是资源还有能力接受更多的工作,不能接受更多工作的程度被视为饱和度。
饱和度:资源不能再服务更多额外工作的程度,通常有等待队列。
错误:错误事件的个数。

……

USE方法会将分析引导到一定数量的关键指标上,这样可以尽快地核实所有的系统资源。在此之后,如果还没有找到问题,那么可以考虑采用其他的方法。

下面具体看一下这10条命令。

uptime

12:05:14 up 25 days, 22:28,  1 user,  load average: 0.00, 0.01, 0.05

快速查看平均负载(任务对CPU资源的需求)。输出中的“load average:”后面的三个数字,是系统在1分钟、5分钟和15分钟内的平均负载。表示负载随时间的变化情况。

它给出的只是一个较为高层的情况,往往需要借助其他工具进一步确认性能问题,有时候需要通过其他一些指标来了解CPU负载,例如vmstat或mpstat。

  1. dmesg | tail
[    7.027092] input: Xen Virtual Keyboard as /devices/virtual/input/input6
[    7.027154] input: Xen Virtual Pointer as /devices/virtual/input/input7
[    7.045185] ppdev: user-space parallel port driver
[    7.137679] alg: No test for __gcm-aes-aesni (__driver-gcm-aes-aesni)
[   12.054020] xenbus_probe_frontend: Waiting for devices to initialise: 25s...20s...15s...10s...5s...0s...

[   37.079248] xenbus_probe_frontend: Timeout connecting to device: device/vkbd/0 (local state 3, remote state 1)
[   37.126790] device-mapper: uevent: version 1.0.3
[   37.126990] device-mapper: ioctl: 4.33.0-ioctl (2015-8-18) initialised: [email protected]
[1136140.265842] UDP: bad checksum. From 120.42.91.41:51069 to 101.200.235.90:137 ulen 58

查看最后10条系统消息。查找可能会引发性能问题的错误。千万不要漏掉这一步。

  1. vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 1918624 232612 2483068    0    0     0    17    3    9  9  0 91  0  0
 0  0      0 1918656 232612 2483068    0    0     0     0  296  686  0  0 100  0  1
 0  0      0 1918656 232612 2483068    0    0     0     0  353  721  0  0 100  0  0

统计虚拟内存信息。参数1指的是打印1秒内的统计信息。

要检查的列:

r:运行队列的长度(这个参数的解释,建议参考《性能之巅》一书)。可以更好地确定CPU的饱和度。“r”值大于CPU数则为饱和。
free:以kb为单位的空闲内存。如果这个值很大,说明有足够的空闲内存。下面将介绍的第7条命令——“free -m”,可以更好地解释空闲内存的状态。
si, so:换入的内存和换出的内存。如果它们不为0,说明内存已经耗尽。
us, sy, id, wa, st:CPU时间的不同组成部分,是所有CPU的平均数。分别表示用户态时间、系统态时间(内核)、空闲、等待I/O以及窃取时间(stolen time,虚拟化环境下,CPU在其他租户上的开销)。

将用户态时间和系统态时间相加,可以判断CPU是否忙碌。如果一直有等待I/O,表明存在磁盘瓶颈。因为任务阻塞等待磁盘I/O,此时CPU是空闲的。可以将等待I/O看作另一种形式的CPU空闲。

I/O处理一定会消耗系统态时间。如果系统时间平均占比很高,比如说超过20%,或许可以深入研究一下:可能是内核处理I/O的效率不高。

  1. mpstat -P ALL 1
Linux 3.10.0-327.18.2.el7.x86_64 (iZ25y9r4qw9Z)         08/02/2016      _x86_64_        (2 CPU)

12:06:57 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
12:06:58 PM  all    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
12:06:58 PM    0    0.00    0.00    0.00    0.00    0.00    0.00    0.99    0.00    0.00   99.01
12:06:58 PM    1    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00

打印每个CPU的状况。可以检查各CPU的负载是否均衡。比如,如果一个CPU很热,可能是单线程应用造成的。

  1. pidstat 1
Linux 3.10.0-327.18.2.el7.x86_64 (iZ25y9r4qw9Z)         08/02/2016      _x86_64_        (2 CPU)

12:07:42 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
12:07:43 PM     0      2811    1.00    1.00    0.00    2.00     1  java

12:07:43 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
12:07:44 PM     0     13550    0.00    1.00    0.00    1.00     1  pidstat

pidstat按进程打印CPU的使用情况。循环输出活动进程的信息。可用于观察模式随时间的变化情况。用户也可以把观察到的信息记录下来,以供分析研究。

像图中的例子,可以看到有2个Java进程消耗了大部分CPU时间。“%CPU”这一列是所有CPU的整体情况,“1591%”这个值表明这2个Java进程几乎占用了16个CPU。

  1. iostat -xz 1
Linux 3.10.0-327.18.2.el7.x86_64 (iZ25y9r4qw9Z)         08/02/2016      _x86_64_        (2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           8.71    0.00    0.05    0.18    0.06   90.99

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
xvda              0.00     1.09    0.02    3.80     0.28    34.62    18.27     0.02    5.55    5.20    5.55   1.25   0.48
xvdb              0.00     0.00    0.00    0.00     0.00     0.00    14.09     0.00    0.51    0.51    0.00   0.46   0.00

这是了解块设备的一个极佳工具,能看到实际负载和性能信息。

r/s, w/s, rkB/s, wkB/s:分别表示每秒发给磁盘设备的读请求数,每秒发给磁盘设备的写请求数,每秒从磁盘设备读取的KB数,每秒向磁盘设备写入的KB数。可以使用它们表示负载特性。性能问题可能就是由过多的负载造成的。
await:平均I/O响应时间,单位为毫秒。包括排队时间和服务时间。如果它大于预期的平均时间,可能是设备已经饱和,也可能是设备存在问题。
avgqu-sz:提交到设备的平均请求数。如果大于1,设备可能已经饱和。
%util:设备使用率。设备忙于处理请求的百分比。如果大于60%,通常会导致较差的性能(可以在await中看出来),不过也与具体的设备有关。如果接近100%,通常意味着设备已经饱和。

如果存储设备是后面有多块磁盘支撑的逻辑磁盘,即使设备使用率是100%,后端磁盘也可能远没有饱和,而是还能处理更多工作。

  1. free -m
              total        used        free      shared  buff/cache   available
Mem:           7566        3039        1874         120        2652        4145
Swap:             0           0           0

主要看最右边的两列:

buffers:用于块设备I/O的缓冲区高速缓存的大小。
cached:文件系统使用的页缓存大小。

我们只需要检查这两个值,如果它们接近0,则会导致更高的磁盘I/O(可以使用iostat确认),性能更糟。图中的例子,这个状况看上去还不错。

  1. sar -n DEV 1
Linux 3.10.0-327.18.2.el7.x86_64 (iZ25y9r4qw9Z)         08/02/2016      _x86_64_        (2 CPU)

12:09:34 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
12:09:35 PM      eth0      0.00      0.00      0.00      0.00      0.00      0.00      0.00
12:09:35 PM      eth1      3.00      3.00      0.20      0.33      0.00      0.00      0.00
12:09:35 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00

12:09:35 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
12:09:36 PM      eth0     18.00     11.00      2.17      1.23      0.00      0.00      0.00
12:09:36 PM      eth1      4.00      6.00      0.84      6.65      0.00      0.00      0.00
12:09:36 PM        lo     62.00     62.00     29.83     29.83      0.00      0.00      0.00

使用该工具检查网络接口的吞吐量,以rxkB/s和txkB/s为手段测量负载。

  1. sar -n TCP,ETCP 1
Linux 3.10.0-327.18.2.el7.x86_64 (iZ25y9r4qw9Z)         08/02/2016      _x86_64_        (2 CPU)

12:09:57 PM  active/s passive/s    iseg/s    oseg/s
12:09:58 PM      1.00      1.00     77.00     64.00

12:09:57 PM  atmptf/s  estres/s retrans/s isegerr/s   orsts/s
12:09:58 PM      0.00      0.00      0.00      0.00      0.00

12:09:58 PM  active/s passive/s    iseg/s    oseg/s
12:09:59 PM      0.00      0.00      1.00      2.00

这是一些关键TCP指标的总结。其中包括:

active/s:每秒本地发起的TCP连接数(比如通过connect())。
passive/s:每秒远端发起的TCP连接数(比如通过accept())。
retrans/s:每秒TCP重传数。

active和passive连接数通常用于粗略地测量服务器负载。方便起见,可以把active看作向外的连接,把passive看作向内的连接;不过也有不严格之处,比如考虑从localhost到localhost的连接。

重传数是网络或服务器问题的一个信号:可能是网络不可靠;也可能是服务器过载和丢包。像图中的例子,每秒只有一个新的TCP连接。

  1. top
top - 12:10:24 up 25 days, 22:34,  1 user,  load average: 0.00, 0.01, 0.05
Tasks: 121 total,   1 running, 112 sleeping,   8 stopped,   0 zombie
%Cpu(s):  8.7 us,  0.1 sy,  0.0 ni, 91.0 id,  0.2 wa,  0.0 hi,  0.0 si,  0.1 st
KiB Mem :  7747772 total,  1918140 free,  3113464 used,  2716168 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  4244188 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                  
    1 root      20   0  125288   5784   2420 S   0.0  0.1   0:34.01 systemd                                                                                                                  
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.00 kthreadd                                                                                                                 
    3 root      20   0       0      0      0 S   0.0  0.0   0:01.70 ksoftirqd/0                                                                                                              
    5 root       0 -20       0      0      0 S   0.0  0.0   0:00.00 kworker/0:0H                                                                                                             
    7 root      rt   0       0      0      0 S   0.0  0.0   0:00.24 migration/0 

top命令包含很多前面检查过的指标。可以用个命令来检查是不是有指标和之前命令的输出差距很大。

top命令有个缺点,很难看出某个指标随时间的变化模式,这种情况下用像vmstat和pidstat这样的命令可能更清楚,它们能提供滚动输出。间歇性问题的一些迹象,如果不能足够快地暂停输出(Ctrl-S暂停,Ctrl-Q继续),可能会错过。

后续分析

可以借助更多命令继续深入挖掘。重点推荐Brendan Gregg的《性能之巅:洞悉系统、企业与云计算》)一书。

本文根据Netflix的技术博客编译整理,结合自己读书的一些心得写就。更多细节,可以点击阅读原文,查看相关博客,或者阅读《性能之巅》一书。

你可能感兴趣的:(系统运维,linux)