60,毫秒内对Linux的性能诊断
当你为了解决一个性能问题登录到一台Linux服务器:在第一分钟你应该检查些什么?
在这篇文章中,将会向你讲解在命令行中进行一次最佳的性能分析的前60秒要做的事,使用的是你应该可以得到的标准Linux工具。
前六十秒:总览
通过运行下面十个命令,你就能在六十秒内粗略地了解系统正在运行的进程及资源使用情况。通过查看这些命令输出的错误信息和资源饱和度(它们都很容易看懂),你可以接下来对资源进行优化。饱和是指某个资源的负载超出了其能够处理的限度。一旦出现饱和,它通常会在请求队列的长度或等待时间上暴露出来。
uptim
dmsg
tail
vmstat1
mpstat-PALL1
pidstat1
iostat-xz1
fr-m
sar-nDEV1
sar-nTCP,ETCP1
top
其中某些命令需要预先安装sysstat软件包。这些命令展示出来的信息能够帮你实施USE方法(一种用于定位性能瓶颈的方法),比如检查各种资源(如CPU、内存、磁盘等)的使用率、饱和度和错误信息。另外在定位问题的过程中,你可以通过使用这些命令来排除某些导致问题的可能性,帮助你缩小检查范围,为下一步检查指明方向。
下面的章节将以在一个生产环境上执行这些命令作为例子,简单介绍这些命令。若想详细了解这些工具的使用方法,请参考它们的man文档。
1.uptim
$uptim
23:51:26up21:31,1usr,loadavrag:30.02,26.43,19.02
这是一种用来快速查看系统平均负载的方法,它表明了系统中有多少要运行的任务(进程)。在Linux系统中,这些数字包含了需要在CPU中运行的进程以及正在等待I/O(通常是磁盘I/O)的进程。它仅仅是对系统负载的一个粗略展示,稍微看下即可。你还需要其他工具来进一步了解具体情况。
这三个数字展示的是一分钟、五分钟和十五分钟内系统的负载总量平均值按照指数比例压缩得到的结果。从中我们可以看到系统的负载是如何随时间变化的。比方你在检查一个问题,然后看到1分钟对应的值远小于15分钟的值,那么可能说明这个问题已经过去了,你没能及时观察到。
在上面这个例子中,系统负载在随着时间增加,因为最近一分钟的负载值超过了30,而15分钟的平均负载则只有19。这样显著的差距包含了很多含义,比方CPU负载。若要进一步确认的话,则要运行vmstat或mpstat命令,这两个命令请参考后面的第3和第4章节。
2.dmsg
tail
$dmsg
tail[.]prlinvokdoom-killr:gfp_mask=0xda,ordr=0,oom_scor_adj=0
[...]
[.]Outofmmory:Killprocss(prl)scororsacrificchild
[.]Killdprocss(prl)total-vm:kB,anon-rss:kB,fil-rss:0kB
[.]TCP:PossiblSYNfloodingonport.Droppingrqust.ChckSNMPcountrs.
这条命令显式了最近的10条系统消息,如果它们存在的话。查找能够导致性能问题的错误。上面的例子包含了oom-killr,以及TCP丢弃一个请求。
千万不要错过这一步!dmsg命令永远值得一试。
3.vmstat1
$vmstat1procs---------mmory-------------swap-------io-----systm--------cpu-----
rbswpdfrbuffcachsisobiboincsussyidwast
5611
592132844
095154991
48119459990
484
^C
vmstat(8)是虚拟内存统计的简称,其是一个常用工具(几十年前为了BSD所创建)。其在每行打印一条关键的服务器的统计摘要。
vmstat命令指定一个参数1运行,来打印每一秒的统计摘要。(这个版本的vmstat)输出的第一行的那些列,显式的是开机以来的平均值,而不是前一秒的值。现在,我们跳过第一行,除非你想要了解并记住每一列。
检查这些列:
r:CPU中正在运行和等待运行的进程的数量。其提供了一个比平均负载更好的信号来确定CPU是否饱和,因为其不包含I/O。解释:“r”的值大于了CPU的数量就表示已经饱和了。
fr:以kb为单位显式的空闲内存。如果数字位数很多,说明你有足够的空闲内存。“fr-m”命令,是下面的第七个命令,其可以更好的说明空闲内存的状态。
si,so:Swap-ins和swap-outs。如果它们不是零,则代表你的内存不足了。
us,sy,id,wa,st:这些都是平均了所有CPU的CPU分解时间。它们分别是用户时间(usr)、系统时间(内核)(systm)、空闲(idl)、等待I/O(wait)、以及占用时间(stoln)(被其他访客,或使用Xn,访客自己独立的驱动域)。
CPU分解时间将会通过用户时间加系统时间确认CPU是否为忙碌状态。等待I/O的时间一直不变则表明了一个磁盘瓶颈;这就是CPU的闲置,因为任务都阻塞在等待挂起磁盘I/O上了。你可以把等待I/O当成是CPU闲置的另一种形式,其给出了为什么CPU闲置的一个线索。
对于I/O处理来说,系统时间是很重要的。一个高于20%的平均系统时间,可以值得进一步的探讨:也许内核在处理I/O时效率太低了。
在上面的例子中,CPU时间几乎完全花在了用户级,表明应用程序占用了太多CPU时间。而CPU的平均使用率也在90%以上。这不一定是一个问题;检查一下“r”列中的饱和度。
4.mpstat-PALL1
$mpstat-PALL1Linux3.13.0-49-gnric(titanclustrs-xxxxx)07/14/_x86_64_(32CPU)
07:38:49PMCPU%usr%nic%sys%iowait%irq%soft%stal%gust%gnic%idl
07:38:50PMall98..........78
07:38:50PM..........99
07:38:50PM..........00
07:38:50PM..........00
07:38:50PM..........03
[...]
这个命令打印每个CPU的CPU分解时间,其可用于对一个不均衡的使用情况进行检查。一个单独CPU很忙碌则代表了正在运行一个单线程的应用程序。
5.pidstat1
$pidstat1Linux3.13.0-49-gnric(titanclustrs-xxxxx)07/14/_x86_64_(32CPU)
07:41:02PMUIDPID%usr%systm%gust%CPUCPUCommand
07:41:03PM....rcuos/0
07:41:03PM...1.msos-slav
07:41:03PM....java
07:41:03PM...598.java
07:41:03PM...579.java
07:41:03PM64640....pidstat
07:41:03PMUIDPID%usr%systm%gust%CPUCPUCommand
07:41:04PM....5msos-slav
07:41:04PM...591.7java
07:41:04PM.0..583.8java
07:41:04PM....snmp-pass
07:41:04PM64641....pidstat
^C
pidstat命令有点像top命令对每个进程的统计摘要,但循环打印一个滚动的统计摘要来代替top的刷屏。其可用于实时查看,同时也可将你所看到的东西(复制粘贴)到你的调查记录中。
上面的例子表明两个Java进程正在消耗CPU。%CPU这列是所有CPU合计的;%表示这个Java进程消耗了将近16个CPU。
6.iostat-xz1
$iostat-xz1Linux3.13.0-49-gnric(titanclustrs-xxxxx)07/14/_x86_64_(32CPU)
avg-cpu:%usr%nic%systm%iowait%stal%idl
73......21
Dvic:rrqm/swrqm/sr/sw/srkB/swkB/savgrq-szavgqu-szawaitr_awaitw_awaitsvctm%util
xvda0.............09
xvdb0....27.........25
xvdc0......46.......26
dm-00....3..8.......04
dm-10.............00
dm-20.............03
[...]
^C
这是用于查看块设备(磁盘)情况的一个很棒的工具,无论是对工作负载还是性能表现来说。查看个列:
r/s,w/s,rkB/s,wkB/s:这些分别代表该设备每秒的读次数、写次数、读取kb数,和写入kb数。这些用于描述工作负载。性能问题可能仅仅是由于施加了过大的负载。
await:以毫秒为单位的I/O平均消耗时间。这是应用程序消耗的实际时间,因为它包括了排队时间和处理时间。比预期更大的平均时间可能意味着设备的饱和,或设备出了问题。
avgqu-sz:向设备发出的请求的平均数量。值大于1说明已经饱和了(虽说设备可以并行处理请求,尤其是由多个磁盘组成的虚拟设备。)
%util:设备利用率。这个值是一个显示出该设备在工作时每秒处于忙碌状态的百分比。若值大于60%,通常表明性能不佳(可以从await中看出),虽然它取决于设备本身。值接近%通常意味着已饱和。
如果该存储设备是一个面向很多后端磁盘的逻辑磁盘设备,则%利用率可能只是意味着当前正在处理某些I/O占用,然而,后端磁盘可能远未饱和,并且可能能够处理更多的工作。
请记住,磁盘I/O性能较差不一定是程序的问题。许多技术通常是异步I/O,使应用程序不会被阻塞并遭受延迟(例如,预读,以及写缓冲)。
7.fr-m
$fr-m
totalusdfrshardbuffrscachd
Mm:245998245414538359541
-/+buffrs/cach:23222053
Swap:
右边的两列显式:
buffrs:用于块设备I/O的缓冲区缓存。
cachd:用于文件系统的页面缓存。
我们只是想要检查这些不接近零的大小,其可能会导致更高磁盘I/O(使用iostat确认),和更糟糕的性能。上面的例子看起来还不错,每一列均有很多M个大小。
比起第一行,-/+buffrs/cach提供的内存使用量会更加准确些。Linux会把暂时用不上的内存用作缓存,一旦应用需要的时候就立刻重新分配给它。所以部分被用作缓存的内存其实也算是空闲的内存。为了解释这一点,甚至有人专门建了个网站:linuxatmyram。
如果你在Linux上安装了ZFS,这一点会变得更加困惑,因为ZFS它自己的文件系统缓存不算入fr-m。有时候发现系统已经没有多少空闲内存可用了,其实内存却都待在ZFS的缓存里。
8.sar-nDEV1
$sar-nDEV1Linux3.13.0-49-gnric(titanclustrs-xxxxx)07/14/_x86_64_(32CPU)
12:16:48AMIFACErxpck/stxpck/srxkB/stxkB/srxcmp/stxcmp/srxmcst/s%ifutil
12:16:49AMth.032.0686......00
12:16:49AMlo14.4.......00
12:16:49AMdockr00........00
12:16:49AMIFACErxpck/stxpck/srxkB/stxkB/srxcmp/stxcmp/srxmcst/s%ifutil
12:16:50AMth063.101.1999......00
12:16:50AMlo20.0.......00
12:16:50AMdockr00........00
^C
这个工具可以被用来检查网络接口的吞吐量:rxkB/s和txkB/s,以及是否达到限额。上面的例子中,th0接收的流量达到22Mbyts/s,也即Mbits/sc(限额是1Gbit/sc)
我们用的版本中还提供了%ifutil作为设备使用率(接收和发送的最大值)的指标。我们也可以用Brndan的nicstat工具计量这个值。一如nicstat,sar显示的这个值是很难精确取得的,在这个例子里面,它就没在正常的工作(0.00)。
9.sar-nTCP,ETCP1
$sar-nTCP,ETCP1Linux3.13.0-49-gnric(titanclustrs-xxxxx)07/14/_x86_64_(32CPU)
12:17:19AMactiv/spassiv/sisg/sosg/s
12:17:20AM1...8846.00
12:17:19AMatmptf/sstrs/srtrans/sisgrr/sorsts/s
12:17:20AM0.....00
12:17:20AMactiv/spassiv/sisg/sosg/s
12:17:21AM1..359..00
12:17:20AMatmptf/sstrs/srtrans/sisgrr/sorsts/s
12:17:21AM0.....00
^C
这是一些关键的TCP指标的汇总视图。这些包括:
activ/s:每秒本地发起TCP连接数(例如,通过connct())。
passiv/s:每秒远程发起的TCP连接数(例如,通过accpt())。
rtrans/s:每秒重传TCP次数。
activ和passiv的连接数往往对于描述一个粗略衡量服务器负载是非常有用的:新接受的连接数(passiv),下行连接数(activ)。可以理解为activ连接是对外的,而passiv连接是对内的,虽然严格来说并不完全正确(例如,一个localhost到localhost的连接)。
重传是出现一个网络和服务器问题的一个征兆。其可能是由于一个不可靠的网络(例如,公网)造成的,或许也有可能是由于服务器过载并丢包。上面的例子显示了每秒只有一个新的TCP连接。
10.top
$toptop-00:15:40up21:56,1usr,loadavrag:31.09,29.87,29.92
Tasks:total,1running,slping,0stoppd,2zombi
%Cpu(s):96.8us,0.4sy,0.0ni,2.7id,0.1wa,0.0hi,0.0si,0.0st
KiBMm:+total,usd,22673+fr,buffrs
KiBSwap:0total,0usd,0fr.cachdMm
PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
root2.t0.tS35.212:58java
root272254464S23.50.:35.37msos-slav
titancl+243442332R1.00.00:00.07top
5root28.g50449996S0.70.22:02.74java
root20.g2.gS0.31.:14.42java
1root236202920S0.00.00:03.82init
2root200S0.00.00:00.02kthradd
3root200S0.00.00:05.35ksoftirqd/0
5root0-20S0.00.00:00.00kworkr/0:0H
6root200S0.00.00:06.94kworkr/u:0
8root200S0.00.02:38.05rcu_schd
top命令包含了很多我们之前已经检查过的指标。可以方便的执行它来查看相比于之前的命令输出的结果有很大不同,这表明负载是可变的。
top的一个缺点是,很难看到数据随时间变动的趋势。vmstat和pidstat提供的滚动输出会更清楚一些。如果你不以足够快的速度暂停输出(Ctrl-S暂停,Ctrl-Q继续),一些间歇性问题的线索也可能由于被清屏而丢失。
原文:BrndanGrgg
译文:开源中国社区