60,000毫秒内对Linux的性能诊断效的方法

转载于:http://www.itxuexiwang.com/a/liunxjishu/2016/0225/168.html?1456484140

60,000毫秒内对Linux的性能诊断

当你为了解决一个性能问题登录到一台Linux服务器:在第一分钟你应该检查些什么?

在Netflix,我们有一个巨大的EC2Linux云,以及大量的性能分析工具来监控和诊断其性能。其中包括用于云监控的Atlas,以及用于按需实例分析的Vector。虽然这些工具可以帮助我们解决大多数问题,但我们有时仍需要登录到一个服务器实例,并运行一些标准Linux性能工具。

在这篇文章中,NetflixPerformanceEngineering团队将会向你讲解在命令行中进行一次最佳的性能分析的前60秒要做的事,使用的是你应该可以得到的标准Linux工具。

前六十秒:总览

通过运行下面十个命令,你就能在六十秒内粗略地了解系统正在运行的进程及资源使用情况。通过查看这些命令输出的错误信息和资源饱和度(它们都很容易看懂),你可以接下来对资源进行优化。饱和是指某个资源的负载超出了其能够处理的限度。一旦出现饱和,它通常会在请求队列的长度或等待时间上暴露出来。

uptime

dmesg|tail

vmstat1

mpstat-PALL1

pidstat1

iostat-xz1

free-m

sar-nDEV1

sar-nTCP,ETCP1

top

其中某些命令需要预先安装sysstat软件包。这些命令展示出来的信息能够帮你实施USE方法(一种用于定位性能瓶颈的方法),比如检查各种资源(如CPU、内存、磁盘等)的使用率、饱和度和错误信息。另外在定位问题的过程中,你可以通过使用这些命令来排除某些导致问题的可能性,帮助你缩小检查范围,为下一步检查指明方向。

下面的章节将以在一个生产环境上执行这些命令作为例子,简单介绍这些命令。若想详细了解这些工具的使用方法,请参考它们的man文档。

1.uptime

$uptime

23:51:26up21:31,1user,loadaverage:30.02,26.43,19.02#p#分页标题#e#

这是一种用来快速查看系统平均负载的方法,它表明了系统中有多少要运行的任务(进程)。在Linux系统中,这些数字包含了需要在CPU中运行的进程以及正在等待I/O(通常是磁盘I/O)的进程。它仅仅是对系统负载的一个粗略展示,稍微看下即可。你还需要其他工具来进一步了解具体情况。

这三个数字展示的是一分钟、五分钟和十五分钟内系统的负载总量平均值按照指数比例压缩得到的结果。从中我们可以看到系统的负载是如何随时间变化的。比方你在检查一个问题,然后看到1分钟对应的值远小于15分钟的值,那么可能说明这个问题已经过去了,你没能及时观察到。

在上面这个例子中,系统负载在随着时间增加,因为最近一分钟的负载值超过了30,而15分钟的平均负载则只有19。这样显著的差距包含了很多含义,比方CPU负载。若要进一步确认的话,则要运行vmstat或mpstat命令,这两个命令请参考后面的第3和第4章节。

2.dmesg|tail

$dmesg|tail[1880957.563150]perlinvokedoom-killer:gfp_mask=0x280da,order=0,oom_score_adj=0

[...]

[1880957.563400]Outofmemory:Killprocess18694(perl)score246orsacrificechild

[1880957.563408]Killedprocess18694(perl)total-vm:1972392kB,anon-rss:1953348kB,file-rss:0kB

[2320864.954447]TCP:PossibleSYNfloodingonport7001.Droppingrequest.CheckSNMPcounters.

这条命令显式了最近的10条系统消息,如果它们存在的话。查找能够导致性能问题的错误。上面的例子包含了oom-killer,以及TCP丢弃一个请求。

千万不要错过这一步!dmesg命令永远值得一试。

3.vmstat1

$vmstat1procs---------memory-------------swap-------io-----system--------cpu-----

rbswpdfreebuffcachesisobiboincsussyidwast

3400200889792737085918280005610961300

320020088992073708591860000592132844282981100

320020089011273708591860000095012154991000

32002008895687371259185600048119002459990000

3200200890208737125918600000158984840981100

^C#p#分页标题#e#

vmstat(8)是虚拟内存统计的简称,其是一个常用工具(几十年前为了BSD所创建)。其在每行打印一条关键的服务器的统计摘要。

vmstat命令指定一个参数1运行,来打印每一秒的统计摘要。(这个版本的vmstat)输出的第一行的那些列,显式的是开机以来的平均值,而不是前一秒的值。现在,我们跳过第一行,除非你想要了解并记住每一列。

检查这些列:

r:CPU中正在运行和等待运行的进程的数量。其提供了一个比平均负载更好的信号来确定CPU是否饱和,因为其不包含I/O。解释:“r”的值大于了CPU的数量就表示已经饱和了。

free:以kb为单位显式的空闲内存。如果数字位数很多,说明你有足够的空闲内存。“free-m”命令,是下面的第七个命令,其可以更好的说明空闲内存的状态。

si,so:Swap-ins和swap-outs。如果它们不是零,则代表你的内存不足了。

us,sy,id,wa,st:这些都是平均了所有CPU的CPU分解时间。它们分别是用户时间(user)、系统时间(内核)(system)、空闲(idle)、等待I/O(wait)、以及占用时间(stolen)(被其他访客,或使用Xen,访客自己独立的驱动域)。

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-generic(titanclusters-xxxxx)07/14/2015_x86_64_(32CPU)

07:38:49PMCPU%usr%nice%sys%iowait%irq%soft%steal%guest%gnice%idle

07:38:50PMall98.470.000.750.000.000.000.000.000.000.78

07:38:50PM096.040.002.970.000.000.000.000.000.000.99

07:38:50PM197.000.001.000.000.000.000.000.000.002.00

07:38:50PM298.000.001.000.000.000.000.000.000.001.00

07:38:50PM396.970.000.000.000.000.000.000.000.003.03

[...]#p#分页标题#e#

这个命令打印每个CPU的CPU分解时间,其可用于对一个不均衡的使用情况进行检查。一个单独CPU很忙碌则代表了正在运行一个单线程的应用程序。

5.pidstat1

$pidstat1Linux3.13.0-49-generic(titanclusters-xxxxx)07/14/2015_x86_64_(32CPU)

07:41:02PMUIDPID%usr%system%guest%CPUCPUCommand

07:41:03PM090.000.940.000.941rcuos/0

07:41:03PM042145.665.660.0011.3215mesos-slave

07:41:03PM043540.940.940.001.898java

07:41:03PM065211596.231.890.001598.1127java

07:41:03PM065641571.707.550.001579.2528java

07:41:03PM60004601540.944.720.005.669pidstat

07:41:03PMUIDPID%usr%system%guest%CPUCPUCommand

07:41:04PM042146.002.000.008.0015mesos-slave

07:41:04PM065211590.001.000.001591.0027java

07:41:04PM065641573.0010.000.001583.0028java

07:41:04PM10867181.000.000.001.000snmp-pass

07:41:04PM60004601541.004.000.005.009pidstat

^C

pidstat命令有点像top命令对每个进程的统计摘要,但循环打印一个滚动的统计摘要来代替top的刷屏。其可用于实时查看,同时也可将你所看到的东西(复制粘贴)到你的调查记录中。

上面的例子表明两个Java进程正在消耗CPU。%CPU这列是所有CPU合计的;1591%表示这个Java进程消耗了将近16个CPU。

6.iostat-xz1

$iostat-xz1Linux3.13.0-49-generic(titanclusters-xxxxx)07/14/2015_x86_64_(32CPU)

avg-cpu:%user%nice%system%iowait%steal%idle

73.960.003.730.030.0622.21

Device:rrqm/swrqm/sr/sw/srkB/swkB/savgrq-szavgqu-szawaitr_awaitw_awaitsvctm%util

xvda0.000.230.210.184.522.0834.370.009.9813.805.422.440.09

xvdb0.010.001.028.94127.97598.53145.790.000.431.780.280.250.25

xvdc0.010.001.028.86127.79595.94146.500.000.451.820.300.270.26

dm-00.000.000.692.3210.4731.6928.010.013.230.713.980.130.04

dm-10.000.000.000.940.013.788.000.33345.840.04346.810.010.00

dm-20.000.000.090.071.350.3622.500.002.550.235.621.780.03

[...]

^C#p#分页标题#e#

这是用于查看块设备(磁盘)情况的一个很棒的工具,无论是对工作负载还是性能表现来说。查看个列:

r/s,w/s,rkB/s,wkB/s:这些分别代表该设备每秒的读次数、写次数、读取kb数,和写入kb数。这些用于描述工作负载。性能问题可能仅仅是由于施加了过大的负载。

await:以毫秒为单位的I/O平均消耗时间。这是应用程序消耗的实际时间,因为它包括了排队时间和处理时间。比预期更大的平均时间可能意味着设备的饱和,或设备出了问题。

avgqu-sz:向设备发出的请求的平均数量。值大于1说明已经饱和了(虽说设备可以并行处理请求,尤其是由多个磁盘组成的虚拟设备。)

%util:设备利用率。这个值是一个显示出该设备在工作时每秒处于忙碌状态的百分比。若值大于60%,通常表明性能不佳(可以从await中看出),虽然它取决于设备本身。值接近100%通常意味着已饱和。

如果该存储设备是一个面向很多后端磁盘的逻辑磁盘设备,则100%利用率可能只是意味着当前正在处理某些I/O占用,然而,后端磁盘可能远未饱和,并且可能能够处理更多的工作。

请记住,磁盘I/O性能较差不一定是程序的问题。许多技术通常是异步I/O,使应用程序不会被阻塞并遭受延迟(例如,预读,以及写缓冲)。

7.free-m

$free-m

totalusedfreesharedbufferscached

Mem:245998245452214538359541

-/+buffers/cache:23944222053

Swap:000

右边的两列显式:

buffers:用于块设备I/O的缓冲区缓存。

cached:用于文件系统的页面缓存。

我们只是想要检查这些不接近零的大小,其可能会导致更高磁盘I/O(使用iostat确认),和更糟糕的性能。上面的例子看起来还不错,每一列均有很多M个大小。

比起第一行,-/+buffers/cache提供的内存使用量会更加准确些。Linux会把暂时用不上的内存用作缓存,一旦应用需要的时候就立刻重新分配给它。所以部分被用作缓存的内存其实也算是空闲的内存。为了解释这一点,甚至有人专门建了个网站:linuxatemyram。#p#分页标题#e#

如果你在Linux上安装了ZFS,这一点会变得更加困惑,因为ZFS它自己的文件系统缓存不算入free-m。有时候发现系统已经没有多少空闲内存可用了,其实内存却都待在ZFS的缓存里。

8.sar-nDEV1

$sar-nDEV1Linux3.13.0-49-generic(titanclusters-xxxxx)07/14/2015_x86_64_(32CPU)

12:16:48AMIFACErxpck/stxpck/srxkB/stxkB/srxcmp/stxcmp/srxmcst/s%ifutil

12:16:49AMeth018763.005032.0020686.42478.300.000.000.000.00

12:16:49AMlo14.0014.001.361.360.000.000.000.00

12:16:49AMdocker00.000.000.000.000.000.000.000.00

12:16:49AMIFACErxpck/stxpck/srxkB/stxkB/srxcmp/stxcmp/srxmcst/s%ifutil

12:16:50AMeth019763.005101.0021999.10482.560.000.000.000.00

12:16:50AMlo20.0020.003.253.250.000.000.000.00

12:16:50AMdocker00.000.000.000.000.000.000.000.00

^C

这个工具可以被用来检查网络接口的吞吐量:rxkB/s和txkB/s,以及是否达到限额。上面的例子中,eth0接收的流量达到22Mbytes/s,也即176Mbits/sec(限额是1Gbit/sec)

我们用的版本中还提供了%ifutil作为设备使用率(接收和发送的最大值)的指标。我们也可以用Brendan的nicstat工具计量这个值。一如nicstat,sar显示的这个值是很难精确取得的,在这个例子里面,它就没在正常的工作(0.00)。

9.sar-nTCP,ETCP1

$sar-nTCP,ETCP1Linux3.13.0-49-generic(titanclusters-xxxxx)07/14/2015_x86_64_(32CPU)

12:17:19AMactive/spassive/siseg/soseg/s

12:17:20AM1.000.0010233.0018846.00

12:17:19AMatmptf/sestres/sretrans/sisegerr/sorsts/s

12:17:20AM0.000.000.000.000.00

12:17:20AMactive/spassive/siseg/soseg/s

12:17:21AM1.000.008359.006039.00

12:17:20AMatmptf/sestres/sretrans/sisegerr/sorsts/s

12:17:21AM0.000.000.000.000.00

^C#p#分页标题#e#

这是一些关键的TCP指标的汇总视图。这些包括:

active/s:每秒本地发起TCP连接数(例如,通过connect())。

passive/s:每秒远程发起的TCP连接数(例如,通过accept())。

retrans/s:每秒重传TCP次数。

active和passive的连接数往往对于描述一个粗略衡量服务器负载是非常有用的:新接受的连接数(passive),下行连接数(active)。可以理解为active连接是对外的,而passive连接是对内的,虽然严格来说并不完全正确(例如,一个localhost到localhost的连接)。

重传是出现一个网络和服务器问题的一个征兆。其可能是由于一个不可靠的网络(例如,公网)造成的,或许也有可能是由于服务器过载并丢包。上面的例子显示了每秒只有一个新的TCP连接。

10.top

$toptop-00:15:40up21:56,1user,loadaverage:31.09,29.87,29.92

Tasks:871total,1running,868sleeping,0stopped,2zombie

%Cpu(s):96.8us,0.4sy,0.0ni,2.7id,0.1wa,0.0hi,0.0si,0.0st

KiBMem:25190241+total,24921688used,22698073+free,60448buffers

KiBSwap:0total,0used,0free.554208cachedMem

PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND

20248root2000.227t0.012t18748S30905.229812:58java

4213root20027225446464044232S23.50.0233:35.37mesos-slave

66128titancl+2002434423321172R1.00.00:00.07top

5235root20038.227g54700449996S0.70.22:02.74java

4299root20020.015g2.682g16836S0.31.133:14.42java

1root2003362029201496S0.00.00:03.82init

2root200000S0.00.00:00.02kthreadd

3root200000S0.00.00:05.35ksoftirqd/0

5root0-20000S0.00.00:00.00kworker/0:0H

6root200000S0.00.00:06.94kworker/u256:0

8root200000S0.00.02:38.05rcu_sched#p#分页标题#e#

top命令包含了很多我们之前已经检查过的指标。可以方便的执行它来查看相比于之前的命令输出的结果有很大不同,这表明负载是可变的。

top的一个缺点是,很难看到数据随时间变动的趋势。vmstat和pidstat提供的滚动输出会更清楚一些。如果你不以足够快的速度暂停输出(Ctrl-S暂停,Ctrl-Q继续),一些间歇性问题的线索也可能由于被清屏而丢失。

后续的分析

还有更多命令和方法可以用于更深入的分析。查看Brendan在Velocity2015大会上的Linux性能工具教程,其中包含了超过40个命令,涵盖了可观测性���标杆管理、调优、静态性能调优、分析,和跟踪等方面。

在全网规模应对系统的可靠性和性能问题是我们的爱好之一。如果你想要加入我们来一起应对这种挑战,我们正在招聘!

相关推荐