iostat 用于输出 CPU 和磁盘 I/O 相关的统计信息。
命令格式:
iostat [ -c | -d ] [ -k | -m ] [ -t ] [ -V ] [ -x ][ device [...] | ALL ] [ -p [ device | ALL ] ] [ interval [ count ]]
1) iostat 命令的简单使用
iostat 命令可以显示 CPU 和 I/O 系统的负载情况及分区状态信息。
直接执行 iostat 命令可以显示下面的内容:
# iostat
# iostat -xm
(带 xm 参数显示扩展信息并将磁盘数据有每扇区改为每兆显示【1扇区等于512字节】)
Linux 2.6.33.3 ((none)) 12/17/10
avg-cpu: %user %nice %system %ioswait %stcal %idle
0.05 0.00 2.00 0.03 0.00 97.92
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s
各项输出项目的含义如下:
avg-cpu 段:
%user: 在用户级别运行所使用 CPU 的百分比。
%nice: nice 操作所使用 CPU 的百分比。
%sys: 在系统级别(kernel)运行所使用 CPU 的百分比。
%iowait: CPU等待硬件 I/O 时,所占用 CPU 百分比。
%idle: CPU 空闲时间的百分比。
Device段:
tps:每秒钟发送到的 I/O 请求数
Blk_read/s:每秒读取的 block 数
Blk_wrtn/s:每秒写入的 block 数
Blk_read:读入的 block 总数
Blk_wrtn:写入的 block 总数
2) iostat 命令的参数说明
iostat 各个参数说明:
-c 仅显示 CPU 统计信息。与 -d 选项互斥。
-d 仅显示磁盘统计信息。与 -c 选项互斥。
-k 以 K 为单位显示每秒的磁盘请求数,默认单位块。
-p device | ALL
与 -x 选项互斥,用于显示块设备及系统分区的统计信息,也可以在 -p 后指定一个设备名,如:
# iostat -p hda
或显示所有设备:
# iostat -p ALL
-t 在输出数据时,打印收集数据的时间。
-V 打印版本号和帮助信息。
-x 输出扩展信息。
3) iostat 命令输出项目说明
Blk_read 读入块的总数
Blk_wrtn 写入块的总数
kB_read/s 每秒从驱动器读入的数据量,单位为 K。
kB_wrtn/s 每秒向驱动器写入的数据量,单位为 K。
kB_read 读入的数据总量,单位为 K。
kB_wrtn 写入的数据总量,单位为 K。
wrqm/s 将写入请求合并后,每秒发送到设备的写入请求数。
r/s 每秒发送到设备的读入请求数。
w/s 每秒发送到设备的写入请求数。
rsec/s 每秒从设备读入的扇区数。
wsec/s 每秒向设备写入的扇区数。
rkB/s 每秒从设备读入的数据量,单位为 K。
wkB/s 每秒向设备写入的数据量,单位为 K。
avgrq-sz 发送到设备的请求的平均大小,单位是 扇区。
avgqu-sz 发送到设备的请求的平均队列长度。
await I/O 请求平均执行时间,包括发送请求和执行的时间。单位是 毫秒。
svctm 发送到设备的 I/O 请求的平均执行时间。单位是 毫秒。
%util 在 I/O 请求发送到设备期间,占用 CPU 时间的百分比。用于显示设备的带宽利用率。
当这个值接近 100% 时,表示设备带宽已经占满。
IO调度器(IO Scheduler)是操作系统用来决定块设备上IO操作提交顺序的方法。存在的目的有两个,一是提高IO吞吐量,二是降低IO响应时间。然而IO吞吐量和IO响应时间往往是矛盾的,为了尽量平衡这两者,IO调度器提供了多种调度算法来适应不同的IO请求场景。其中,对数据库这种随机读写的场景最有利的算法是DEANLINE。接着我们按照从简单到复杂的顺序,迅速扫一下Linux 2.6内核提供的几种IO调度算法。
1、NOOP NOOP算法的全写为No Operation。该算法实现了最最简单的FIFO队列,所有IO请求大致按照先来后到的顺序进行操作。之所以说“大致”,原因是NOOP在FIFO的基础上还做了相邻IO请求的合并,并不是完完全全按照先进先出的规则满足IO请求。 假设有如下的io请求序列: 100,500,101,10,56,1000 NOOP将会按照如下顺序满足: 100(101),500,10,56,1000
2、CFQ CFQ算法的全写为Completely Fair Queuing。该算法的特点是按照IO请求的地址进行排序,而不是按照先来后到的顺序来进行响应。 假设有如下的io请求序列: 100,500,101,10,56,1000 CFQ将会按照如下顺序满足: 100,101,500,1000,10,56在传统的SAS盘上,磁盘寻道花去了绝大多数的IO响应时间。CFQ的出发点是对IO地址进行排序,以尽量少的磁盘旋转次数来满足尽可能多的IO请求。在CFQ算法下,SAS盘的吞吐量大大提高了。但是相比于NOOP的缺点是,先来的IO请求并不一定能被满足,可能会出现饿死的情况。
3、DEADLINE DEADLINE在CFQ的基础上,解决了IO请求饿死的极端情况。除了CFQ本身具有的IO排序队列之外,DEADLINE额外分别为读IO和写IO提供了FIFO队列。读FIFO队列的最大等待时间为500ms,写FIFO队列的最大等待时间为5s。FIFO队列内的IO请求优先级要比CFQ队列中的高,,而读FIFO队列的优先级又比写FIFO队列的优先级高。优先级可以表示如下: FIFO(Read) > FIFO(Write) > CFQ
4、ANTICIPATORY CFQ和DEADLINE考虑的焦点在于满足零散IO请求上。对于连续的IO请求,比如顺序读,并没有做优化。为了满足随机IO和顺序IO混合的场景,Linux还支持ANTICIPATORY调度算法。ANTICIPATORY的在DEADLINE的基础上,为每个读IO都设置了6ms的等待时间窗口。如果在这6ms内OS收到了相邻位置的读IO请求,就可以立即满足。
IO调度器算法的选择,既取决于硬件特征,也取决于应用场景。 在传统的SAS盘上,CFQ、DEADLINE、ANTICIPATORY都是不错的选择;对于专属的数据库服务器,DEADLINE的吞吐量和响应时间都表现良好。然而在新兴的固态硬盘比如SSD、Fusion IO上,最简单的NOOP反而可能是最好的算法,因为其他三个算法的优化是基于缩短寻道时间的,而固态硬盘没有所谓的寻道时间且IO响应时间非常短。
查看和修改IO调度器的算法非常简单。假设我们要对sda进行操作,如下所示: cat /sys/block/sda/queue/scheduler echo “cfq” > /sys/block/sda/queue/scheduler