操作系统状态
操作系统会提供一些帮助发现操作系统和硬件正在做什么的工具。其中包括最常用的工具iostat和vmstat。如果系统不能提供它们中的任何一个,有可能提供了相似的替代品。当然目的不是让大家熟练使用iostat和vmstat,而是告诉大家用类似的工具诊断问题时应该看什么指标。除了这些,操作系统也许还提供了其他的工具,如mpstat或者sar.如果对系统的其他部分感兴趣,例如网络,你可能希望使用ifconfig(除了其他信息,它能显示了多少次网络错误)或者netstat.
默认情况下,vmstat和iostat只是生成一个报告,展示自系统启动依赖很多计数器的平均值,这其实没什么用。然而,两个工具都可以给出一个间隔参数,让它们生成增量值得报告,展示服务器正在做什么,这更有用
如何阅读vmstat的输出
我们先看一个vmstat的例子。用下面的命令让它每5秒钟打印出一个报告:
vmstat 5
可以用Ctrl +C停止vmstat,可以看到输出依赖于所用的操作系统,因此可能需要阅读一下手册来解读报告。刚启动不久,即使采用增量报告,第一行的值还是显示自系统启动以来的平均值,第二行展示现在正在发生的情况,接下来的行会展示每5秒的间隔内发生了什么。每一列的含义在头部,如下所示:
- 1.procs
r这一列展示了多少进程正在等待CPU。b列显示多少进程正在不可中断地休眠(通常意味着它们在等待IO,例如磁盘、网络、用户输入,等等)。 - 2.memory
swapd列显示多少块被换出到了磁盘(页面交换)/剩下地三列显示了多少块时空闲的(未被使用)、多少块正在被用作缓冲,以及多少正在被用作操作系统的缓存。 - 3.swap
这些列显示页面交换活动:每秒有多少块正在被换入(从磁盘)和换出(到磁盘)。它们比监控swapd列重要多了。大部分时间我们喜欢看到si和so列时0,并且我们很明确不希望看到每秒超过10个块。突发性的高峰一样很糟糕。 - 4.io
这些列显示有多少块从块设备读取(bi)和写出(bo)。这通常反应了硬盘IO - 5.system
这些列显示了每秒中断(in)和上下文切换(cs)的数量 - 6.cpu
这些列显示所有的CPU时间花费在各类操作的百分比,包括执行用户代码(非内核)、执行系统代码(内核)、空闲,以及等待IO.如果正在使用虚拟化,则第五个列可能是st,显示了从虚拟机中"偷走"的百分比。这关系到那些虚拟机想运行但是系统管理程序转而运行其他的对象的时间。如果虚拟机不希望运行任何对象,但是系统管理程序运行了其他对象,这不算被偷走的CPU时间
vmstat的输出跟系统有关,所以如果看到跟展示的例子不同的输出,应该阅读系统的vmstat(8)手册。一个重要的提示是:内存、交换区,以及IO统计是块数而不是i字节。在GNU/Linux,块大小通常是1024字节
使用如下命令查看系统手册:
man vmstat
vmstat(8)使用手册如图
如何阅读iostat的输出
现在让我们转移到iostat。默认情况下,它显示了与vmstat相同的CPU使用信息。我们通常只是对IO统计感兴趣,所以使用下面的命令之战是扩展的设备统计:
iostat -dx 5
与vmstat一样,第一行报告显示的是自系统启动以来的平均值(通常删掉它节省空间),然后接下来的报告显示了增量的平均值,每个设备一行。有多种选项显示和隐藏列。官方文档有点难以理解,因此我们必须从源码中挖掘真正显示的内容是什么。说明的列信息如下:
- 1.rrqm/s和wrqm/s
每秒合并的读和写请求。"合并的"意味着操作系统从队列中拿出多个逻辑请求合并为一个请求到实际磁盘 - 2.r/s和w/s
每秒发送到设备的读和写请求 - 3.rsec/s和wsec/s
每秒读和写的扇区数。有些系统也输出为rkB/s和wkB/s,意味着每秒读写的千字节数。为了简洁,省略了那些指标说明。 - 4.avgrq-sz
请求的扇区数 - 5.avgqu-sz
在设备队列中等待的请求数 - 6.await
磁盘队列上花费的毫秒数。很不幸,iostat没有独立统计读和写的请求,它们实际上不应该被一起平均 - 7.svctm
服务请求花费的毫秒数,不包括排队时间 - 8.%util
至少有一个活跃请求所占时间的百分比。如果熟悉队列理论张利用率的标准定义,那么这个命名很莫名其妙。它其实不是设备的利用率。超过一块硬盘的设备(例如RAID控制器)比一块硬盘的设备可以支持更高的并发,但是%util从来不会超过100%,除非在计算机时有四舍五入的错误。因此,这个指标无法真实反映设备的利用率,实际上跟文档说的相反,除非只有一块物理磁盘的特殊例子。
可以用iostat的输出推断某些关于机器IO自系统的实际情况。一个重要的度量标准时请求服务的并发数。因为读写的单位时每秒而服务时间的单位是千分之一秒,所以可以利用利特尔法则(Littele’s Law)得到下面的公式,计算出设备服务的并发请求数(另一种计算并发的方式是通过平均队列大小、服务时间,以及平均等大i时间:(avuqu_sz * svctm) / await):
concurrency = (r/s + w/s) * (svctm/1000)
把数字带入并发公式,可以得到(0.38 + 0.02) * (0.43 / 1000) = 0.000172.由于我这台服务器配置是乞丐版的,所以得到的并发数比较低。这意味着在一个采样周期内,这个设备平均要服务0.000172次的请求。