如何查询及测试Linux系统的磁盘IO性能
简介
我们知道 Linux 存储系统 I/O 栈由文件系统层(file system layer)、通用块层( general block layer)和设备层(device layer)构成。
其中,通用块层是 Linux 磁盘 I/O 的核心。向上,它为访问文件系统和应用程序的块设备提供了标准接口;向下,它将各种异构磁盘设备抽象为一个统一的块设备,并响应文件系统和应用程序发送的 I/O。
磁盘 IO 的使用率是指磁盘处理 IO 的时间百分比,可以反映磁盘的负载情况。过高的使用率(比如超过 80%)通常意味着磁盘 IO 存在性能瓶颈。
查看磁盘 IO 的使用率有多种方法,例如:
- 使用 top 命令,通过查看 CPU 的 wa% 值来判断当前磁盘 IO 性能
- 使用 iostat 命令,通过查看 %util 列来判断每个设备的使用率
- 使用sar命令,通过查看 %util 列来判断每个设备的使用率
- 使用 pidstat 命令,通过查看 kB_rd/s 和 kB_wr/s 列来判断每个进程的读写速度
Linux 磁盘性能指标说明
在衡量磁盘性能时,我们经常提到五个常见指标:利用率、饱和度、IOPS、吞吐量和响应时间。这五个指标是衡量磁盘性能的基本指标。
- 使用率(Utilization):磁盘处理 I/O 的时间百分比。过度使用(如超过 80%)通常意味着磁盘 I/O 存在性能瓶颈。
- 饱和度(Saturation):指磁盘处理 I/O 的繁忙程度。过度饱和意味着磁盘存在严重的性能瓶颈。当饱和度为 100% 时,磁盘无法接受新的 I/O 请求。
- IOPS(Input/Output Per Second):指每秒 I/O 请求的数量。
- 吞吐量(Throughput):每秒 I/O 请求的大小。
- 响应时间(Response time):指发送 I/O 请求和接收响应之间的间隔时间。
这里需要注意的是,关于利用率,我们只考虑有无 I/O,而不考虑 I/O 的大小。也就是说,当利用率为 100% 时,磁盘仍有可能接受新的 I/O 请求。
一般来说,在为应用选择服务器时,首先要对磁盘的 I/O 性能进行基准测试,这样才能准确评估磁盘性能,以判断是否能够满足应用的需求。当然,这需要你在随机读、随机写、顺序读、顺序写等各种应用场景下测试不同 I/O 大小的性能。
IOPS 与吞吐量的关系
每秒 I/O 吞吐量= IOPS * 平均 I/O SIZE。从公式可以看出: I/O SIZE 越大,IOPS 越高,那么每秒 I/O 的吞吐量就越高。因此,我们会认为 IOPS 和吞吐量的数值越高越好。实际上,对于一个磁盘来讲,这两个参数均有其最大值,而且这两个参数也存在着一定的关系。
IOPS可细分为如下几个指标:
- Toatal IOPS,混合读写和顺序随机I/O负载情况下的磁盘IOPS,这个与实际I/O情况最为相符,大多数应用关注此指标。
- Random Read IOPS,100%随机读负载情况下的IOPS。
- Random Write IOPS,100%随机写负载情况下的IOPS。
- Sequential Read IOPS,100%顺序读负载情况下的IOPS。
- Sequential Write IOPS,100%顺序写负载情况下的IOPS。
磁盘 I/O 观察
首先要观察的是每个磁盘的使用情况。iostat 是最常用的磁盘 I/O 性能观察工具。它提供了各种常用性能指标,例如每个磁盘的利用率、IOPS 和吞吐量。当然,这些指标实际上来自 /proc/diskstats
。
iostat
iostat主要用于监控系统设备的 IO 负载情况,iostat 首次运行时显示自系统启动开始的各项统计信息,之后运行 iostat 将显示自上次运行该命令以后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。
iostat,对系统的磁盘操作活动进行监视。它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况。iostat也有一个弱点,就是它不能对某个进程进行深入分析,仅对系统的整体情况进行分析。
iostat命令参数说明:
- -c: 显示CPU使用情况
- -d: 显示磁盘使用情况
- -N: 显示磁盘阵列(LVM) 信息
- -n: 显示NFS 使用情况
- -k: 以 KB 为单位显示
- -m: 以 M 为单位显示
- -t: 报告每秒向终端读取和写入的字符数和CPU的信息
- -V: 显示版本信息
- -x: 显示IO相关的详细信息
- -p [磁盘] : 显示磁盘和分区的情况
备注:
如果%iowait的值过高,表示硬盘存在I/O瓶颈,%idle值高,表示CPU较空闲。
如果%idle值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量。
如果%idle值持续低于10,那么系统的CPU处理能力相对较低,表明系统中最需要解决的资源是CPU。
CPU属性值说明:
- %user: CPU处在用户模式下的时间百分比
- %nice: CPU处在带NICE值的用户模式下的时间百分比
- %system: CPU处在系统模式下的时间百分比
- %iowait: CPU等待输入输出完成时间的百分比
- %steal: 管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比
- %idle: CPU空闲时间百分比
磁盘属性值说明:
- device: 磁盘名称
- tps: 每秒钟发送到的I/O请求数
- Blk_read/s: 每秒读取的block数
- Blk_wrtn/s: 每秒写入的block数
- Blk_read: 读入的block总数
- Blk_wrtn: 写入的block总数
磁盘IO相关的详细说明:
- rrqm/s: 每秒进行 merge 的读操作数目。即 rmerge/s
- wrqm/s: 每秒进行 merge 的写操作数目。即 wmerge/s
- r/s: 每秒完成的读 I/O 设备次数。即 rio/s
- w/s: 每秒完成的写 I/O 设备次数。即 wio/s
- rkB/s: 每秒读K字节数。是 rsect/s 的一半,因为每扇区大小为512字节。
- wkB/s: 每秒写K字节数。是 wsect/s 的一半
- avgrq-sz: 平均每次设备I/O操作的数据大小 (扇区)
- avgqu-sz: 平均I/O队列长度
- rsec/s: 每秒读扇区数。即 rsect/s
- wsec/s: 每秒写扇区数。即 wsect/s
- r_await: 每个读操作平均所需的时间,不仅包括硬盘设备读操作的时间,还包括了在kernel队列中等待的时间
- w_await: 每个写操作平均所需的时间,不仅包括硬盘设备写操作的时间,还包括了在kernel队列中等待的时间
- await: 平均每次设备I/O操作的等待时间 (毫秒)
- svctm: 平均每次设备I/O操作的服务时间 (毫秒)
- %util: 一秒中有百分之多少的时间用于 I/O 操作,即被io消耗的cpu百分比
备注:
如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。
如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;
如果 await 远大于 svctm,说明I/O 队列太长,io响应太慢,则需要进行必要优化。
如果avgqu-sz比较大,也表示有当量io在等待。
示例:查看cpu状态
1 | iostat -c 1 1 |
示例:查看磁盘使用率和响应时间
1 2 | # -d 显示磁盘使用情况,-x 显示详细信息 iostat -d -x -k 1 1 |
其他示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # 间隔1秒,总共显示5次 iostat 1 5 # 每隔2秒,显示一次设备统计信息 iostat -d 2 # 每隔2秒,显示一次设备统计信息,总共输出3次 iostat -d 2 3 # 每隔2秒显示一次sda, sdb两个设备的扩展统计信息,共输出3次 iostat -x sda sdb 2 3 # 每隔2秒显示一次sda及上面所有分区的统计信息,共输出3次 iostat -p sda 2 3 # 以M为单位显示所有信息 iostat -m |
以下是 iostat
的输出示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # -d -x means display all disk I/O performance $ iostat -d -x 1 Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util loop0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 loop1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 [root@server-68.2.stage.polex.io var ]$ iostat -dxk 1 2 Linux 3.10.0-693.5.2.el7.x86_64 (server-68) 03/11/2019 _x86_64_ (64 CPU) Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 0.06 0.32 2.08 1.44 72.78 61.81 0.14 59.32 0.51 68.37 5.68 1.36 sdb 0.00 0.00 0.03 0.00 1.15 0.00 86.32 0.00 0.17 0.17 0.00 0.16 0.00 dm-0 0.00 0.00 0.00 0.24 0.02 1.56 13.22 0.01 44.55 6.36 44.71 13.25 0.32 dm-1 0.00 0.00 0.32 1.90 1.32 71.22 65.30 0.14 62.43 0.49 72.79 4.75 1.06 dm-2 0.00 0.00 0.00 0.00 0.00 0.00 26.79 0.00 28.06 4.68 38.98 5.18 0.00 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 0.00 0.00 3.00 0.00 16.00 10.67 0.26 86.33 0.00 86.33 42.33 12.70 sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 dm-1 0.00 0.00 0.00 3.00 0.00 16.00 10.67 0.26 86.33 0.00 86.33 42.33 12.70 dm-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 |
在上述指标中,您需要注意的是:
%util
是我们前面提到的磁盘 I/O 使用情况r/s
和w/s
是 IOPSrkB/s
和wkB/s
是吞吐量r_await
和w_await
是响应时间
您可能已经注意到 iostat
不能直接获取磁盘的饱和度。事实上,通常没有什么简单的方法可以测量饱和度。但是,您可以将观察到的平均请求队列长度或完成读写请求的等待时间与基准测试(例如通过 fio)的结果进行比较,以综合评估磁盘饱和度。
该命令的结果与上面 sar -d -p 1 2
命令类似,实际使用中主要还是看 await svctm %util 参数。
sar
sar 命令是分析系统瓶颈的神器,可以用来查看 CPU 、内存、磁盘、网络等性能。
sar 命令查看当前磁盘性能的命令为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | [root@server-68.2.stage.polex.io var ]$ sar -d -p 1 2 Linux 3.10.0-693.5.2.el7.x86_64 (server-68) 03/11/2019 _x86_64_ (64 CPU) 02:28:54 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util 02:28:55 PM sda 1.00 0.00 3.00 3.00 0.01 9.00 9.00 0.90 02:28:55 PM sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:28:55 PM polex_pv-rootvol 1.00 0.00 3.00 3.00 0.01 9.00 9.00 0.90 02:28:55 PM polex_pv-varvol 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:28:55 PM polex_pv-homevol 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:28:55 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util 02:28:56 PM sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:28:56 PM sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:28:56 PM polex_pv-rootvol 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:28:56 PM polex_pv-varvol 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 02:28:56 PM polex_pv-homevol 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util Average: sda 0.50 0.00 1.50 3.00 0.00 9.00 9.00 0.45 Average: sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: polex_pv-rootvol 0.50 0.00 1.50 3.00 0.00 9.00 9.00 0.45 Average: polex_pv-varvol 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: polex_pv-homevol 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 |
其中, “-d”参数代表查看磁盘性能,“-p”参数代表将 dev 设备按照 sda,sdb……名称显示,“1”代表每隔1s采取一次数值,“2”代表总共采取2次数值。
- await:平均每次设备 I/O 操作的等待时间(以毫秒为单位)。
- svctm:平均每次设备 I/O 操作的服务时间(以毫秒为单位)。
- %util:一秒中有百分之几的时间用于 I/O 操作。
对于磁盘 IO 性能,一般有如下评判标准:
正常情况下 svctm 应该是小于 await 值的,而 svctm 的大小和磁盘性能有关,CPU 、内存的负荷也会对 svctm 值造成影响,过多的请求也会间接的导致 svctm 值的增加。
await 值的大小一般取决与 svctm 的值和 I/O 队列长度以 及I/O 请求模式,如果 svctm 的值与 await 很接近,表示几乎没有 I/O 等待,磁盘性能很好,如果 await 的值远高于 svctm 的值,则表示 I/O 队列等待太长,系统上运行的应用程序将变慢,此时可以通过更换更快的硬盘来解决问题。
%util 项的值也是衡量磁盘 I/O 的一个重要指标,如果 %util 接近 100% ,表示磁盘产生的 I/O 请求太多,I/O 系统已经满负荷的在工作,该磁盘可能存在瓶颈。长期下去,势必影响系统的性能,可以通过优化程序或者通过更换更高、更快的磁盘来解决此问题。
默认情况下,sar从最近的0点0分开始显示数据;如果想继续查看一天前的报告;可以查看保存在/var/log/sa/下的sar日志:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | [root@server-68.2.stage.polex.io var ]$ sar -d -p -f /var/log/sa/sa11 | more Linux 3.10.0-693.5.2.el7.x86_64 (server-68) 03/11/2019 _x86_64_ (64 CPU) 09:50:01 AM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util 10:00:01 AM sda 0.51 0.00 9.06 17.82 0.02 37.65 14.65 0.74 10:00:01 AM sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 10:00:01 AM polex_pv-rootvol 0.22 0.00 2.50 11.56 0.01 37.44 14.10 0.31 10:00:01 AM polex_pv-varvol 0.30 0.00 6.55 21.97 0.01 38.55 14.73 0.44 10:00:01 AM polex_pv-homevol 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 10:10:01 AM sda 0.79 3.45 13.18 21.06 0.04 51.81 11.03 0.87 10:10:01 AM sdb 0.04 3.45 0.00 86.33 0.00 0.25 0.25 0.00 10:10:01 AM polex_pv-rootvol 0.26 0.00 3.08 11.85 0.01 50.21 17.88 0.46 10:10:01 AM polex_pv-varvol 0.54 3.45 10.10 24.95 0.03 52.58 7.49 0.41 10:10:01 AM polex_pv-homevol 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 10:20:01 AM sda 0.65 0.00 10.43 16.11 0.03 38.67 10.99 0.71 10:20:01 AM sdb 0.04 3.46 0.00 86.33 0.00 0.08 0.08 0.00 |
pidstat
pidstat,用于监控全部或指定进程的cpu、内存、线程、设备IO等系统资源的占用情况。pidstat首次运行时显示自系统启动开始的各项统计信息,之后运行pidstat将显示自上次运行该命令以后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。
命令参数说明:
- -u:默认的参数,显示各个进程的cpu使用统计
- -r:显示各个进程的内存使用统计
- -d:显示各个进程的IO使用情况
- -p:指定进程号
- -w:显示每个进程的上下文切换情况
- -t:显示选择任务的线程的统计信息外的额外信息
- -T TASK CHILD | ALL :TASK表示报告独立的task,CHILD关键字表示报告进程下所有线程统计信息。ALL表示报告独立的task和task下面的所有线程。注意:task和子线程的全局的统计信息和pidstat选项无关。这些统计信息不会对应到当前的统计间隔,这些统计信息只有在子线程kill或者完成的时候才会被收集
- -V:显示版本号
- -h:在一行上显示了所有活动,这样其他程序可以容易解析
- -I:在SMP环境,表示任务的CPU使用率/内核数量
- -l:显示命令名和所有参数
示例:查看所有进程的CPU使用情况
1 2 3 4 5 6 7 8 9 10 11 12 13 | pidstat -u -p ALL Linux 3.10.0-957.el7.x86_64 (VM-75-65) 04/24/2020 _x86_64_ (4 CPU) 02:10:43 PM UID PID %usr %system %guest %CPU CPU Command 02:10:43 PM 0 1 0.00 0.01 0.00 0.01 0 systemd 02:10:43 PM 0 2 0.00 0.00 0.00 0.00 1 kthreadd 02:10:43 PM 0 3 0.00 0.06 0.00 0.06 0 ksoftirqd/0 02:10:43 PM 0 7 0.00 0.00 0.00 0.00 0 migration/0 02:10:43 PM 0 8 0.00 0.00 0.00 0.00 3 rcu_bh 02:10:43 PM 0 9 0.00 0.16 0.00 0.16 2 rcu_sched 02:10:43 PM 0 10 0.00 0.00 0.00 0.00 0 lru-add-drain 02:10:43 PM 0 11 0.00 0.00 0.00 0.00 0 watchdog/0 |
属性值说明:
- PID:进程ID
- %usr:进程在用户空间占用cpu的百分比
- %system:进程在内核空间占用cpu的百分比
- %guest:进程在虚拟机占用cpu的百分比
- %CPU:进程占用cpu的百分比
- CPU:处理进程的cpu编号
- Command:当前进程对应的命令
示例:查看指定进程的内存使用情况
指定PID为29468的进程内存使用情况,每秒展示一次,展示四次! 也可以直接pidstat -r,是全部进程的内存使用情况!
1 2 3 4 5 6 7 8 9 10 | pidstat -r -p 29468 1 4 Linux 3.10.0-957.el7.x86_64 (VM-75-65) 04/24/2020 _x86_64_ (4 CPU) 02:16:00 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command 02:16:01 PM 0 29468 0.00 0.00 413040 4104 0.03 docker-containe 02:16:02 PM 0 29468 0.00 0.00 413040 4104 0.03 docker-containe 02:16:03 PM 0 29468 0.00 0.00 413040 4104 0.03 docker-containe 02:16:04 PM 0 29468 0.00 0.00 413040 4104 0.03 docker-containe Average: 0 29468 0.00 0.00 413040 4104 0.03 docker-containe |
属性值说明:
- PID:进程标识符
- Minflt/s:任务每秒发生的次要错误,不需要从磁盘中加载页
- Majflt/s:任务每秒发生的主要错误,需要从磁盘中加载页
- VSZ:虚拟地址大小,虚拟内存的使用KB
- RSS:常驻集合大小,非交换区内存的使用KB
- Command:task命令名
也可以直接pidstat -r,是全部进程的内存使用情况!
示例:显示各个进程IO的使用情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | pidstat -d Linux 3.10.0-957.el7.x86_64 (VM-75-65) 04/24/2020 _x86_64_ (4 CPU) 02:25:35 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command 02:25:35 PM 0 1 6.42 242.84 0.72 systemd 02:25:35 PM 0 2432 0.00 0.00 0.00 xfsaild/sda3 02:25:35 PM 0 2501 0.00 0.00 0.00 systemd-journal 02:25:35 PM 0 2522 0.00 0.00 0.00 lvmetad 02:25:35 PM 0 2539 0.35 0.00 0.00 systemd-udevd 02:25:35 PM 0 4863 0.00 0.17 0.00 auditd 02:25:35 PM 32 4893 0.00 0.00 0.00 rpcbind 02:25:35 PM 0 4894 0.00 0.00 0.00 smartd 02:25:35 PM 0 4896 0.00 0.00 0.00 irqbalance |
属性值说明:
- PID:进程ID
- kB_rd/s:每秒从磁盘读取的KB
- kB_wr/s:每秒写入磁盘KB
- kB_ccwr/s:任务取消的写入磁盘的KB。当任务截断脏的pagecache的时候会发生。
- COMMAND:task的命令名
示例:进程的上下文切换情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | pidstat -w Linux 3.10.0-957.el7.x86_64 (VM-75-65) 04/24/2020 _x86_64_ (4 CPU) 02:26:50 PM UID PID cswch/s nvcswch/s Command 02:26:50 PM 0 1 0.36 0.00 systemd 02:26:50 PM 0 2 0.01 0.00 kthreadd 02:26:50 PM 0 3 10.42 0.00 ksoftirqd/0 02:26:50 PM 0 5 0.00 0.00 kworker/0:0H 02:26:50 PM 0 7 1.77 0.00 migration/0 02:26:50 PM 0 8 0.00 0.00 rcu_bh 02:26:50 PM 0 9 114.23 0.00 rcu_sched 02:26:50 PM 0 10 0.00 0.00 lru-add-drain 02:26:50 PM 0 11 0.25 0.00 watchdog/0 02:26:50 PM 0 12 0.25 0.00 watchdog/1 |
属性值说明:
- PID:进程ID
- cswch/s:每秒主动任务上下文切换数量
- nvcswch/s:每秒被动任务上下文切换数量
- Command:命令名
示例:显示特定进程的线程统计情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | pidstat -p 12920 -t Linux 2.6.32-573.el6.x86_64 (VM-75-64) 04/24/2020 _x86_64_ (8 CPU) 02:20:23 PM TGID TID %usr %system %guest %CPU CPU Command 02:20:23 PM 12920 - 0.00 0.00 0.00 0.00 3 java 02:20:23 PM - 12920 0.00 0.00 0.00 0.00 3 |__java 02:20:23 PM - 12922 0.00 0.00 0.00 0.00 6 |__java 02:20:23 PM - 12923 0.00 0.00 0.00 0.00 0 |__java 02:20:23 PM - 12924 0.00 0.00 0.00 0.00 0 |__java 02:20:23 PM - 12925 0.00 0.00 0.00 0.00 2 |__java 02:20:23 PM - 12926 0.00 0.00 0.00 0.00 5 |__java 02:20:23 PM - 12927 0.00 0.00 0.00 0.00 4 |__java 02:20:23 PM - 12928 0.00 0.00 0.00 0.00 1 |__java 02:20:23 PM - 12930 0.00 0.00 0.00 0.00 5 |__java 02:20:23 PM - 12931 0.00 0.00 0.00 0.00 5 |__java 02:20:23 PM - 12932 0.00 0.00 0.00 0.00 3 |__java 02:20:23 PM - 12933 0.00 0.00 0.00 0.00 4 |__java 02:20:23 PM - 12934 0.00 0.00 0.00 0.00 4 |__java 02:20:23 PM - 12935 0.00 0.00 0.00 0.00 5 |__java 02:20:23 PM - 12936 0.00 0.00 0.00 0.00 3 |__java 02:20:23 PM - 12938 0.00 0.00 0.00 0.00 5 |__java 02:20:23 PM - 12939 0.00 0.00 0.00 0.00 1 |__java 02:20:23 PM - 12940 0.00 0.00 0.00 0.00 6 |__java 02:20:23 PM - 12941 0.00 0.00 0.00 0.00 2 |__java 02:20:23 PM - 12943 0.00 0.00 0.00 0.00 6 |__java |
属性值说明:
- TGID:主线程的表示
- TID:线程id
- %usr:进程在用户空间占用cpu的百分比
- %system:进程在内核空间占用cpu的百分比
- %guest:进程在虚拟机占用cpu的百分比
- %CPU:进程占用cpu的百分比
- CPU:处理进程的cpu编号
- Command:当前进程对应的命令
iotop
iotop是一个用来监视磁盘I/O使用状况的 top 类工具,可监测到哪一个程序使用的磁盘IO的信息。
命令参数说明:
- -o, --only只显示正在产生I/O的进程或线程。除了传参,可以在运行过程中按o生效。
- -b, --batch非交互模式,一般用来记录日志。
- -n NUM, --iter=NUM设置监测的次数,默认无限。在非交互模式下很有用。
- -d SEC, --delay=SEC设置每次监测的间隔,默认1秒,接受非整形数据例如1.1。
- -p PID, --pid=PID指定监测的进程/线程。
- -u USER, --user=USER指定监测某个用户产生的I/O。
- -P, --processes仅显示进程,默认iotop显示所有线程。
- -a, --accumulated显示累积的I/O,而不是带宽。
- -k, --kilobytes使用kB单位,而不是对人友好的单位。在非交互模式下,脚本编程有用。
- -t, --time 加上时间戳,非交互非模式。
- -q, --quiet 禁止头几行,非交互模式。有三种指定方式,其中,-q表示只在第一次监测时显示列名,-qq表示永远不显示列名,-qqq表示永远不显示I/O汇总。
交互按键:
和top命令类似,iotop也支持以下几个交互按键。
- left和right方向键:改变排序。
- r:反向排序。
- o:切换至选项--only。
- p:切换至--processes选项。
- a:切换至--accumulated选项。
- q:退出。
- i:改变线程的优先级。
只显示正在产生I/O的进程或线程(交互式)
除了传参,可以在运行过程中按o生效。
1 | iotop -o |
按时间间隔刷新(交互式)
每间隔2秒,输出5次。
1 | iotop -d 2 -n 5 |
按时间间隔刷新,输出到屏幕(非交互式)
每间隔2秒,输出5次。也可输出到日志文本,用于监控某时间段的io信息.
1 | iotop -botq -n 5 -d 2 |
输出PID为8382的进程的磁盘IO信息(非交互式)
1 | iotop -botq -p 8382 |
每隔3秒采集一次磁盘io,输出时间,一共采集30次,想一直抓的话把30去掉即可,注意磁盘空余量
1 2 | iotop -b -o -d 3 -t -qqq -n 30 iotop -b -o -d 1 -qqq |awk '{ print $0"\t" strftime("%Y-%m-%d-%H:%M:%S",systime()) } ' |
通过这个命令我们可以确认如下信息:
- 问题发生的时间
- 产生IO的进程id以及进程参数(command)
- 进程产生的吞吐量(如果有多个可以把qqq去掉可显示总量)
- 进程占用当前IO的百分比
vmstat
vmstat 命令使用方法很简单:
1 2 3 4 5 6 7 8 9 | [root@server-68.2.stage.polex.io var ]$ vmstat 2 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 3 0 0 93221488 4176 69117136 0 0 0 1 0 0 4 1 94 0 0 2 0 0 93226048 4176 69117128 0 0 0 0 33326 36671 18 2 80 0 0 1 0 0 93218776 4176 69117104 0 0 0 9 26225 21588 18 2 80 0 0 1 0 0 93226072 4176 69117072 0 0 0 0 13271 25857 5 0 94 0 0 0 0 0 93223984 4176 69117040 0 0 0 5 34637 24444 20 2 78 0 0 11 0 0 93219248 4176 69117184 0 0 0 0 30736 20671 8 2 90 0 0 |
输出结果中,bi bo 可以表示磁盘当前性能:
- bi 块设备每秒接收的块数量,这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是 1024 byte 。
- bo 块设备每秒发送的块数量,例如我们读取文件,bo 就要大于0。bi 和 bo 一般都要接近 0,不然就是 IO 过于频繁,需要调整。
top 命令
top 命令通过查看 CPU 的 wa% 值来判断当前磁盘 IO 性能,如果这个数值过大,很可能是磁盘 IO 太高了,当然也可能是其他原因,例如网络 IO 过高等。
进程 I/O 观察
除了每个磁盘的 I/O 情况,每个进程的 I/O 情况也是大家关注的重点。
上面提到的 iostat
只提供了观察磁盘的整体 I/O 性能数据。缺点是无法知道哪些进程正在读写磁盘。要观察进程的 I/O,还可以使用 pidstat
和 iotop
工具。
例如,要使用 pidstat
1 2 3 | $ pidstat -d 1 13:39:51 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command 13:39:52 102 916 0.00 4.00 0.00 0 rsyslogd |
从 pidstat
的输出可以看出,它可以实时查看每个进程的 I/O 情况,这包括以下内容:
- 用户 ID (
UID
) 和进程 ID (PID
)。 - 每秒读取的数据大小 (
kB_rd/s
),以 KB 为单位。 - 每秒发出的写请求数据的大小(
kB_wr/s
),单位为KB。 - 每秒取消写入请求的数据大小 (
kB_ccwr/s
),以 KB 为单位。 - 块 I/O 延迟 (
iodelay
),包括等待同步块(synchronized block)I/O 和换入块(swap-in block)I/O 完成的时间,以时钟周期为单位。
除了使用 pidstat
实时查看进程磁盘 I/O 外,还有一个磁盘性能分析的常用方法是根据 I/O 大小对进程进行排序。为此,我推荐 iotop
工具。它是一个类似于 top
的工具,您可以按 I/O 大小对进程进行排序,并找到具有更大 I/O 的进程。
1 2 3 4 5 | $ iotop Total DISK READ : 0.00 B/s | Total DISK WRITE : 7.85 K/s Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 15055 be/3 root 0.00 B/s 7.85 K/s 0.00 % 0.00 % systemd-journald |
从该输出可以看到,前两行分别代表进程的磁盘读写总大小和磁盘的实际读写总大小。由于缓存、缓冲区、I/O 合并等因素,它们可能不相等。
剩下的部分从各个角度代表了进程的 I/O 情况,包括 线程 ID、I/O 优先级、每秒磁盘读取大小、每秒磁盘写入大小、换入百分比和等待 I/O 时钟百分比。
测试磁盘 IO 性能
hdparm 命令
hdparm 命令提供了一个命令行的接口用于读取和设置IDE或SCSI硬盘参数,注意该命令只能测试磁盘的读取速率。
要了解Linux磁盘性能的基本特性,可以使用hdparm
的-T
和-t
参数:
-T
使用Linux磁盘缓存来测试磁盘读取性能,表示的是如果磁盘足够快速并始终运行时的读取性能-t
虽然也使用缓存,但是不会预先缓存结果,表示的是磁盘顺序存储信息的吞吐量。
不过,hdparm
不是真实性能的测试工具,由于它执行的是非常底层的操作,所以一旦你在磁盘上创建了文件系统,测试结果会完全不同。并且对于顺序访问和随机访问,性能有巨大差异。
例如,测试 sda 磁盘的读取速率:
1 2 3 4 5 | [root@server-68.2.stage.polex.io var ]$ hdparm -Tt /dev/polex_pv/varvol /dev/polex_pv/varvol: Timing cached reads: 15588 MB in 2.00 seconds = 7803.05 MB/sec Timing buffered disk reads: 1128 MB in 3.01 seconds = 374.90 MB/sec |
从测试结果看出,带有缓存的读取速率为:7803.05MB/s ,磁盘的实际读取速率为:374.90 MB/s 。
dd 命令
Linux dd 命令用于读取、转换并输出数据。dd 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。
我们可以利用 dd 命令的复制功能,测试某个磁盘的 IO 性能,须要注意的是 dd 命令只能大致测出磁盘的 IO 性能,不是非常准确。
测试写性能命令:
1 2 3 4 5 6 7 8 | [root@server-68.2.stage.polex.io var ]$ time dd if=/dev/zero of=test.file bs=1G count=2 oflag=direct 2+0 records in 2+0 records out 2147483648 bytes (2.1 GB) copied, 13.5487 s, 159 MB/s real 0m13.556s user 0m0.000s sys 0m0.888s |
可以看到,该分区磁盘写入速率为 159M/s,其中:
- /dev/zero 伪设备,会产生空字符流,对它不会产生 IO 。
- if 参数用来指定 dd 命令读取的文件。
- of 参数用来指定 dd 命令写入的文件。
- bs 参数代表每次写入的块的大小。
- count 参数用来指定写入的块的个数。
- offlag=direc 参数测试 IO 时必须指定,代表直接写如磁盘,不使用 cache 。
测试读性能命令:
1 2 3 4 | [root@server-68.2.stage.polex.io var ]$ dd if=test.file of=/dev/null iflag=direct 4194304+0 records in 4194304+0 records out 2147483648 bytes (2.1 GB) copied, 4.87976 s, 440 MB/s |
可以看到,该分区的读取速率为 440MB/s
fio 命令
fio 命令是专门测试 iops 的命令,比 dd 命令准确,fio 命令的参数很多,详细请参考:https://www.xmmup.com/ioyacegongjuzhifio.html
结论
在本文中,我介绍了 Linux 磁盘 I/O 的性能指标和查看性能工具。我们通常使用 IOPS、吞吐量、利用率、饱和度和响应时间等几个指标来评估磁盘的 I/O 性能。
可以使用 iostat
、sar
获取磁盘的 I/O 情况,也可以使用 pidstat
、iotop
等观察进程的 I/O 情况。但在分析这些性能指标时,要注意结合读写比率、I/O 类型、I/O 大小等综合分析。
1 2 3 4 5 | iostat -dxk 5 sar -d -p 2 iotop -b -o -d 2 -t -qqq -n 5 iotop -o -d 2 iotop -botq -p PID |
参考
https://www.xmmup.com/linuxfuwuqixingnengjiankong.html
https://blog.devgenius.io/linux-disk-i-o-performance-1e920faba23
https://www.cnblogs.com/mauricewei/p/10502539.html
https://zhuanlan.zhihu.com/p/433309959
https://elf8848.iteye.com/blog/2168876
https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/sar.html
http://blog.sina.com.cn/s/blog_62b832910102w3zt.html
https://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858810.html