这里所有的工具,都可以通过man 获得它的帮助文档,这里只介绍一些常规用法。
stat工具
vmstat
我们先看一个vmstat 的例子。用下面的命令让它每5秒中打印一个报告。
可以用ctrl+c停止vmstat。vmstat的常规用法是vmstat interval times,即每隔interval秒采 样一次,共采样times次,如果省略times,则一直采集数据到用户手动停止。
第一行的值是显示了自系统启动以来的平均值,第二行开始展示现在正在发生的情况,接下来的行会显示每5秒的间隔内发生了什么。每一列的含义在头部,如下所示:
r这一列显示了多少进程正在等待cpu,b列显示多少进程正在不可中断的休眠(通常意味着它们在等待IO ,例如磁盘,网络,用户输入,等等)。
swapd列显示了多少块被换出到了磁盘(页面交换)。剩下的三个列显示了多少块是空闲的(未被使用),多少块正在被用作缓冲区,以及多少正在被用作操作系统的缓存。
这些列显示页面交换活动:每秒有多少块正在被换入(从磁盘)和换出(到磁盘)。它们比监控swpd列重要多了。大部分时间我们希望看到si 和so 列是0,并且我们很明确不希望看到每秒超过10个块。
这些列显示了多少块从块设备读取(bi)和写出(bo)。这通常反映了硬盘I/O。
这些列显示了每秒中断(in)和上下文切换(cs)的数量。除非上下文切换超过100 000次或更多,一般不用担心上下文切换。
这些列显示所有的CPU时间花费在各类操作的百分比,包括执行用户代码(非内核),执行系统代码(内核),空闲以及等待IO。如果正在使用虚拟化,第5列可能是st,显示了从虚拟机中”偷走”的百分比。
内存不足的表现:free memory 急剧减少,回收buffer和cache也无济于事,大量使用交换分区(swpd),页面交换(swap)频繁,读写磁盘数量(io)增多,缺页中断(in)增多,上下文切换(cs)次数增多,等待IO的进程数(b)增多,大量CPU时间用于等待IO(wa)。
iostat
现在让我们转移到iostat 。默认情况下,它显示了与vmstat 相同的CPU 使用信息。我们通常只对I/O统计感兴趣,所以使用下面的命令只展示扩展的设备统计。
与vmstat一样,第一行报告显示的是自系统启动以来的平均值,(通常删掉它节省空间),然后接下来的报告显示了增量的平均值,每个设备一行。
有多种选项显示和隐藏列。官方文档有点难以理解,因此我们必须从源码中挖掘真正显示的内容是什么。说明的列信息如下:
为了看懂Linux的磁盘IO指标,先了解一些常见的缩写习惯:rq是request,r是read,w是write,qu是queue,sz是size的,a是average,tm是time,svc是service。
rrqm/s 和 wrqm/s
每秒合并的读和写请求。”合并的”意味着操作系统从队列中拿出多个逻辑请求合并为一个请求到实际磁盘。
r/s 和 w/s
每秒发送到设备的读和写请求数。
rsec/s 和 wsec/s
每秒读和写的扇区数。有些系统也输出为rKB/s和wKB/s ,意味每秒读写的千字节数。(iostat -dkx interval times)
avgrq-sz
请求的扇区数。(读扇区数 + 写扇区数) / (读请求次数 + 写请求次数)
avgqu-sz
在设备队列中等待的请求数。即队列的平均长度。
await
每个IO请求花费的时间,包括在队列中的等待时间和实际请求(服务)时间。
svctm
实际请求(服务)时间,以毫秒为单位,不包括排队时间。
%util
至少有一个活跃请求所占时间的百分比。更好的说法应该是,服务时间所占的百分比。以上面的输出为例。 一秒中内,读了2.5次,写了1.8次,每次请求的实际请求时间(不包括排队时间)为6.0ms,那么总的时间花费为(2.5+1.8)*6.0ms,即25.8ms,0.0258秒,转换成百分比再四舍五入就得到了util的值2.6%。
%util: When this figure is consistently approaching above 80% you will need to take any of the following actions - * increasing RAM so dependence on disk reduces * increasing RAID controller cache so disk dependence decreases * increasing number of disks so disk throughput increases (more spindles working parallely) * horizontal partitioning
下面这个公式可以计算一个请求在整个请求期间,有多少时间用以等待。当这个值大于50%,说明整个请求期间,花费了更多时间在队列中等待;如果这个数很大,则应该采取相应措施。
IO瓶颈的症状: 1. %util 很高 2. await 远大于svctm 3. avgqu-sz 比较大
下面解释了iowait的作用,需要注意的是,高速CPU也可能导致iowait取值较大。
%iowait: This number shows the % of time the CPU is wasting in waiting for IO. A part of this number can result from network IO, which can be avoided by using an Async IO library. The rest of it is simply an indication of how IO-bound your application is. You can reduce this number by ensuring that disk IO operations take less time, more data is available in RAM, increasing disk throughput by increasing number of disks in a RAID array, using SSD (Check my post on Solid State drives vs Hard Drives) for portions of the data or all of the data etc
上面的解释主要参考《高性能mysql》和这篇博客。
例子
cpu 密集型机器
cpu 密集型服务器的vmstat 输出通常在us 列会有一个很高的值,报告了花费在非内核代码上的cpu 时钟;也可能在sy 列有很高的值,表示系统cpu 利用率,超过20% 就足以令人不安了。在大部分情况下,也会有进程队列排队时间(在r列报告的)。下面是一个列子:
如果我们在同一台及其上观察iostat 的输出(再次剔除显示启动以来平均值的第一行),可以发现磁盘利用率低于50%:
这台机器不是IO密集型的,但是依然有相当数量的IO发生,在数据库服务器中这种情况很少见。另一方面,传统的Web 服务器会消耗掉大量的CPU 资源,但是很少发生IO,所以Web 服务器的输出不会像这个例子。
IO 密集型机器
在IO密集型工作负载下,CPU花费大量时间在等待IO请求完成。这意味着vmstat 会显示很多处理器在非中断休眠(b列)状态,并且在wa 这一列的值很高,下面是个例子:
这台机器的iostat 输出显示硬盘一直很忙:
%util的值可能因为四舍五入的错误超过100%。什么迹象意味着机器是IO密集的呢?只要有足够的缓冲来服务写请求,即使机器正在做大量的写操作,也可能可以满足,但是却通常意味着硬盘可能会无法满足读请求。这听起来好像违反直觉,但是如果思考读和写的本质,就不会这么认为了:
想想这种方式:你可以发出一个写请求到缓冲区的某个地方,然后过一会完成。甚至可以每秒发出很多这样的请求。如果缓冲区正确工作,并且有足够的空间,每个请求都可以很快完成,并且实际上写到物理硬盘是被重新排序后更有效地批量操作的。然而,没有办法对读操作这么做————不管多小或多少的请求,都不可能让硬盘响应说:”这是你的数据,我等一会读它”。这就是为什么读需要IO等待是可以理解的原因。
发生内存交换的机器
一台正在发生内存交换的机器可能在swpd 列有一个很高的值,也可能不高。但是可以看到si 和 so 列有很高的值,这是我们不希望看到的。下面是一台内存交换严重的机器的vmstat 输出:
空闲的机器
下面是一台空闲机器上的vmstat输出。可以看到idle列显示CPU是100%的空闲。
dstat
dstat 显示了cpu使用情况,磁盘io 情况,网络发包情况和换页情况。
个人觉得,iostat和vmstat 的输出虽然详细,但是不够直观,不如dstat 好用。而且,dstat输出是彩色的,可读性更强。现在dstat作为我首选的,查看系统状态的工具。
dstat使用时,直接输入命令即可,不用任何参数。也可以通过指定参数来显示更加详细的信息。
dstat -cdlmnpsy
pidstat
了解系统IO的情况大多数是通过iostat来获取的,这个粒度只能精确到每个设备。通常我们会想了 解每个进程,线程层面发起了多少IO,在Linux 2.6.20之前除了用systemtap这样的工具来实现 是没有其他方法的,因为系统没有暴露这方面的统计。现在可以通过一个名为pidstat的工具, 它的使用方法如下:
pidstat -d interval
此外,pidstat 还可以用以统计CPU使用信息。
pidstat -u interval
统计内存信息:
pidstat -r interval
mpstat
mpstat 用来统计多核处理器中,每一个处理器的使用情况。mpstat使用方法很简单,常见用法如下:
mpstat -P ALL interval times
不出意外,读者执行上面的命令,看不出个所以然来,试试在运行下面这条命令的同时,查看mpstat的输出。
sysbench --test=cpu --cpu-max-prime=20000 run
注意:sysbench是一个基准测试工具,可以用来测试cpu,io,mutex,oltp等。在Debain系统下, 通过下面的命令安装:
sudo apt-get install sysbench
netstat
netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。
就我自己而言,经常使用的用法如下:
netstat -npl
上面这条命令可以查看你要打开的端口是否已经打开,以此来作为程序是否已经启动的依据。
netstat 还有很多其他的用法,在《TCP/IP详解》一书中,作者喜欢用netstat命令来打印路由表,使用方法如下:
netstat -rn
其中,flag域的解释如下:
netstat 也可以提供系统上的接口信息:
netstat -in
这个命令打印每个接口的MTU,输入分组数,输入错误,输出分组数,输出错误,冲突以及当前的输出队列的长度。