在我们进行数据库读写的时候,有可能遇到cpu密集型的问题,也可能遇到I/O密集型的问题,cup密集型的问题是指把大量的时间花在了计算上,而I/O密集型的数据是指把大量时间花在了连接的I/O上。
操作系统为我们提供了硬件正在做什么的工具,vmstat和Iostat.如果系统不提供它们中的任何一个,可能提供了相似的替代品。
默认情况下,vmstat和iostat只是生成一个报告,展示自系统启动以来很多计数器的平均值,这其实没什么用。然而,两个工具都可以给出一个间隔参数,让他们生成增量值的报告,真是服务器正在做什么,这更有用。(第一行显示的是系统自启动以来的统计,通常可以忽略这一行)
如何阅读vmstat的输出
我们看一个vmstat的例子。用下面的命令让它每5秒钟打印出一个报告:
$ vmstat 5
procs -------------------memory--------------- -----swap----- -----io------ --system-- -----------cpu--------------
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 2632 25728 23176 740244 0 0 527 521 11 3 10 1 86 3
0 0 2632 27808 23180 738248 0 0 2 430 222 66 2 0 97 0
刚启动不久,即使采用增量报告,第一行的值还是显示子系统启动以来的平均值,第二行开始展示现在正在发生的情况,接下来的行会展示每5秒间隔内发生了什么。每一类的含义在头部,如下所示:
procs
r这一列展示了多少进程正在等待cpu,b列显示多少进程正在不可中断地休眠(通常意味着他们在等待I/O,例如磁盘、网络、用户输入、等等)。
memory
swpd列显示多少块被换出到了磁盘(页面交换)。剩下的三个列展示了多少块是空闲的(未被使用),多少块正在被用作i缓存,以及多少正在被用作操作系统的缓存
swap
这些列显示页面交换活动:每秒有多少块正在被换入(从磁盘)和换出(到磁盘)、他们比监控swpd列重要多了。
大部分时间我们喜欢看到si和so是0,并且我们很明确不希望看到每秒超过10个块。突发性的高峰一样很糟糕。
io
这些列显示了有多少块从块设备读取(bi)和写出(bo)。这通常反映了磁盘I/O.
system
这些列显示了每秒中断(in)和上下文切换(cs)的数量
cpu
这些列显示所有的CPU时间花费在各类操作的百分比,包括执行用户代码(非内核)、执行系统代码(内核)、空闲,以及等待i/O。
在Linux中,快大小同通常是1024字节。
如何阅读iostat的输出
现在让我们移到iostat。默认情况下,它显示了与vmstat相同的cpu使用信息。我们通常只对i/o统计感兴趣,所以使用下面的命令只展示扩展的设备统计:
$ iostat -dx -5
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 1.6 2.8 2.5 1.8 138.8 36.9 40.7 0.1 23.2 6.0 2.6
与vmstat 一样,第一行报告显示的是自系统启动以来的平均值(通常删除它节省空间),然后接下来的报告显示了增量的平均值,每个设备一行。
有多种选项显示和隐藏列。官方文档有点难以理解,因此我们必须从源码中挖掘真正展示的内容是什么。说明的列信息如下:
rrqm/s和wrqm/s
每秒合并的读和写请求。“合并的”意味着操作系统从队列中拿出多个逻辑请求合并为一个请求到实际磁盘。
r/s和w/s
每秒发送到设备的读和写请求。
rsec/s和wsec/s
每秒读和写的扇区数。有些系统也输出为rkB/s和wkB/s,意为每秒读写的千字字节数。
avgrq-sz
请求的扇区数。
avgqu-sz
在设备队列中等待的请求数。
await
磁盘排队上花费的毫秒数。很不幸,iostat没有独立统计读和写的请求,他们实际上不应该被一起平均。当你诊断性能案例时这通常很重要。
svctm
磁盘请求花费的毫秒数不包括排队时间。
%util
一秒中有百分之多少的时间用于 I/O 操作,或者说一秒中有多少时间 I/O。
下面有一篇介绍iostat的文章,我觉得还不错,可以供有兴趣的人看看用法:
CPU密集型的机器
CPU密集型服务器vmstat输出通常在us列会有一个很高的值,报告了花费在非内核代码上的cpu利用率;也可能在sy列有很高的值,表示系统CPU利用率,超过20%就足以令人不安了。注意,关于上下文切换(在cs)列,除非超过100000次或更多,一般都不用担心上下文切换。当操作系统停止一个进程转而运行另一个进程时就会产生上下文切换。
例如,一个查询语句在Innodb上执行了一个非覆盖索引扫描,就会先从索引中读取元素,然后根据索引再从磁盘上读取页面。如果页面不再操作系统缓存中,就需要从磁盘进行物理读取,这就会导致上下文切换中断进程处理,直到i/O完成。这样一个查询可以导致大量的上下文切换。
IO密集型机器
在I/O密集型工作负载下,CPU花费大量时间在等待I/O请求完成。这意味着vastat会显示很多处理器在非中断休眠(b列)状态,并且在wa这一列的值很高。