Linux 磁盘IO读写性能排查指南

准备工作

确保系统中已安装下列工具:

  • sysstat(包含 iostat
  • smartmontools(包含 smartctl
  • hdparm
  • dd(自带,一般Linux默认安装)

安装示例(基于Debian/Ubuntu):

1
sudo apt-get install sysstat smartmontools hdparm

排查步骤

1. 检查系统整体负载

首先,使用 tophtop 查看系统整体负载情况,关注:

  • CPU 利用率中是否有较高的 iowait 时间
  • 是否存在异常进程占用大量IO资源、

在 top 的第一屏中,会有一行显示 CPU 的整体利用率,通常格式类似于:

1
%Cpu(s):  3.0 us,  1.0 sy,  0.0 ni, 95.0 id,  1.0 wa,  0.0 hi,  0.0 si,  0.0 st
  • us (user):用户空间占用的 CPU 时间。
  • sy (system):内核空间占用的 CPU 时间。
  • ni (nice):低优先级进程占用的 CPU 时间。
  • id (idle):空闲时间。
  • wa (iowait):等待 I/O 完成的 CPU 时间。
  • hi/si:硬中断/软中断占用的 CPU 时间。
  • st:被虚拟机偷取的 CPU 时间。

1.1 查看 iowait 指标

  • iowait (wa) 表示 CPU 等待磁盘 I/O 操作完成的时间比例。

    • 正常情况下,wa 数值较低(例如 3%~5%),说明磁盘 I/O 响应较快。
    • 如果发现 wa 值持续较高(如 10% 以上),则可能存在磁盘读写瓶颈或响应缓慢的问题。

例如,你提到的 wa 为 3.6%,总体来说处于正常水平,但仍需结合其它指标进一步确认系统的整体 I/O 状态。

1.2 检查进程状态

在 top 的进程列表中,重点关注以下几点:

  • 进程状态(STAT 列)

    • D 状态:表示进程处于不可中断睡眠状态,通常与等待 I/O 有关。如果有进程长时间处于 D 状态,可能正在等待磁盘操作。
  • CPU 占用(%CPU 列)

    • 检查是否有某个或多个进程占用异常高的 CPU 资源。高 CPU 占用本身不一定表示 I/O 问题,但如果结合高 iowait,则可能是 I/O 密集型进程在等待磁盘响应。
  • 累计时间(TIME+ 列)

    • 表示进程自启动以来累计使用的 CPU 时间,对于长时间运行且 I/O 密集的进程,可以帮助判断其负载情况。

例如,在进程列表中看到如下行:

1
2
PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
1234 root 20 0 123456 7890 2345 D 0.0 0.1 0:00.12 some_process

这里,进程 some_process 的状态为 D,表示它可能正在等待磁盘 I/O 操作。如果这种状态的进程数量较多或持续时间较长,则需要重点排查。

2. 使用 iostat 查看磁盘利用率

1
2
3
4
5
6
7
[root@luffy ~]# iostat --help
Usage: iostat [ options ] [ <interval> [ <count> ] ]
Options are:
[ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ]
[ -j { ID | LABEL | PATH | UUID | ... } ]
[ [ -T ] -g <group_name> ] [ -p [ <device> [,...] | ALL ] ]
[ <device> [...] | ALL ]

选项:

  • -c:仅显示 CPU 使用情况;
  • -d:仅显示设备利用率;
  • -k:显示状态以千字节每秒为单位,而不使用块每秒;
  • -m:显示状态以兆字节每秒为单位;
  • -p:仅显示块设备和所有被使用的其他分区的状态;
  • -t:显示每个报告产生时的时间;
  • -V:显示版号并退出;
  • -x:显示扩展状态。

参数:

间隔时间:每次报告的间隔时间(秒);

次数:显示报告的次数。

2.1 使用示例

-d 参数

参数 -d 表示,显示设备(磁盘)使用状态。

1
2
3
4
5
6
7
8
9
[root@luffy ~]# iostat -d 10
Linux 3.10.0-1160.105.1.el7.x86_64 (luffy.super) 03/13/2025 _x86_64_ (16 CPU)

Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sdb 0.00 0.00 0.00 10929 2048
sda 28.07 2.73 257.90 6566161 619903894
scd0 0.47 17.33 0.00 41664468 0
dm-0 30.26 2.72 257.89 6531997 619895566
dm-1 0.00 0.00 0.00 2312 6240

输出信息的含义:

  • tps:该设备每秒的传输次数。”一次传输” 意思是 “一次 I/O 请求”。多个逻辑请求可能会被合并为 “一次 I/O 请求”。”一次传输” 请求的大小是未知的。
  • kB_read/s:每秒从设备读取的数据量;
  • kB_wrtn/s:每秒向设备写入的数据量;
  • kB_read:读取的总数据量;
  • kB_wrtn:写入的总数量数据量。

这些单位都为 Kilobytes。

-c 参数

-c 参数显示 CPU 使用情况:

1
2
3
4
5
[root@luffy ~]#  iostat -c
Linux 3.10.0-1160.105.1.el7.x86_64 (luffy.super) 03/13/2025 _x86_64_ (16 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
0.37 0.00 0.18 0.02 0.00 99.43

输出信息的含义:

  • % user:CPU 处在用户模式下的时间百分比。
  • % nice:CPU 处在带 NICE 值的用户模式下的时间百分比。
  • % system:CPU 处在系统模式下的时间百分比。
  • % iowait:CPU 等待输入输出完成时间的百分比。
  • % steal:管理程序维护另一个虚拟处理器时,虚拟 CPU 的无意识等待时间百分比。
  • % idle:CPU 空闲时间百分比。

备注:如果 % iowait 的值过高,表示硬盘存在 I/O 瓶颈,% idle 值高,表示 CPU 较空闲,如果 % idle 值高但系统响应慢时,有可能是 CPU 等待分配内存,此时应加大内存容量。% idle 值如果持续低于 10,那么系统的 CPU 处理能力相对较低,表明系统中最需要解决的资源是 CPU。

-x 参数

每隔三秒查看一次完整信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@luffy ~]# iostat -x 3
Linux 3.10.0-1160.105.1.el7.x86_64 (luffy.super) 03/13/2025 _x86_64_ (16 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
0.37 0.00 0.18 0.02 0.00 99.43

Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sdb 0.00 0.00 0.00 0.00 0.00 0.00 104.24 0.00 3.22 3.03 15.00 2.40 0.00
sda 0.00 2.19 0.03 28.04 2.73 257.98 18.57 0.53 19.00 34.10 18.98 0.34 0.96
scd0 0.00 0.00 0.47 0.00 17.33 0.00 74.29 0.00 0.10 0.10 0.00 0.08 0.00
dm-0 0.00 0.00 0.03 30.23 2.72 257.97 17.23 0.62 20.42 34.30 20.40 0.32 0.96
dm-1 0.00 0.00 0.00 0.00 0.00 0.00 10.21 0.00 32.21 11.90 33.71 1.18 0.00

avg-cpu: %user %nice %system %iowait %steal %idle
0.60 0.00 0.40 0.19 0.00 98.81

Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
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
sda 0.00 51.00 0.00 304.00 0.00 2977.33 19.59 8.30 27.30 0.00 27.30 0.32 9.77
scd0 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 355.00 0.00 2977.33 16.77 11.77 33.14 0.00 33.14 0.28 9.77
dm-1 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

输出信息的含义:

  • rrqm/s:每秒这个设备相关的读取请求有多少被 Merge 了(当系统调用需要读取数据的时候,VFS 将请求发到各个 FS,如果 FS 发现不同的读取请求读取的是相同 Block 的数据,FS 会将这个请求合并 Merge);
  • wrqm/s:每秒这个设备相关的写入请求有多少被 Merge 了。
  • r/s:每秒读取的扇区数;
  • w/s:每秒写入的扇区数。
  • rKB/s:每秒发送到设备的读取请求数。
  • wKB/s:每秒向设备发出的写请求数。
  • avgrq-sz 平均请求扇区的大小
  • avgqu-sz 是平均请求队列的长度。毫无疑问,队列长度越短越好。
  • await: 每一个 IO 请求的处理的平均时间(单位是微秒毫秒)。这里可以理解为 IO 的响应时间,一般地系统 IO 响应时间应该低于 5ms,如果大于 10ms 就比较大了。这个时间包括了队列时间和服务时间,也就是说,一般情况下,await 大于 svctm,它们的差值越小,则说明队列时间越短,反之差值越大,队列时间越长,说明系统出了问题。
  • svctm 表示平均每次设备 I/O 操作的服务时间(以毫秒为单位)。如果 svctm 的值与 await 很接近,表示几乎没有 I/O 等待,磁盘性能很好,如果 await 的值远高于 svctm 的值,则表示 I/O 队列等待太长, 系统上运行的应用程序将变慢。
  • % util: 在统计时间内所有处理 IO 时间,除以总共统计时间。例如,如果统计间隔 1 秒,该设备有 0.8 秒在处理 IO,而 0.2 秒闲置,那么该设备的 % util = 0.8/1 = 80%,所以该参数暗示了设备的繁忙程度。一般地,如果该参数是 100% 表示设备已经接近满负荷运行了(当然如果是多磁盘,即使 % util 是 100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)。

iostat -x 1 10 是指执行 10 次,每秒输出一次信息,适合快速查看一定时间内的性能数

iostat -x 1 每秒输出一次信息,持续输出,适合长期监控和观察系统性能,直到手动结束

3. 进行读写性能测试

dd 命令

  • **if**:指定输入文件(**input file**)。
  • **of**:指定输出文件(**output file**

写入测试

使用 dd 命令测试写入速度:

1
dd if=/dev/zero of=testfile bs=1G count=1 oflag=dsync
  • if=/dev/zero:输入来自一个特殊设备,产生持续的零。
  • bs=1G:设置块大小为 1 GB。
  • count=1:只写入一个块。

常见正常输出示例:

1
2
3
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB) copied, 10.1 s, 106 MB/s

说明:对于机械硬盘,速度可能在50-150 MB/s之间;对于SSD,速度往往更高。

读取测试

测试写入后文件的读取速度:

1
dd if=testfile of=/dev/null bs=1G count=1

正常输出示例:

1
1073741824 bytes (1.1 GB) copied, 4.2 s, 256 MB/s

其他工具

可以利用 hdparm 测试缓存读取与磁盘实际读取速度:

1
hdparm -tT /dev/sda

正常情况下输出示例:

1
2
3
4
Timing cached reads:
12000 MB in 2.00 seconds = 6000.00 MB/sec
Timing buffered disk reads:
150 MB in 3.00 seconds = 50.00 MB/sec

4. 检查磁盘健康状态

使用 smartctl 检查硬盘健康信息,查看是否存在错误或预警:

1
sudo smartctl -a /dev/sda

关注项:

  • Reallocated_Sector_Ct(重新分配扇区数)
  • Current_Pending_Sector(待处理扇区)
  • SMART整体状态(通常显示为 PASSED 表示正常)

5. 查看系统日志

通过 dmesg 或查看 /var/log/syslog/var/log/messages 等日志文件,关注磁盘相关错误信息:

1
dmesg | grep -i error

1
grep -i 'sda' /var/log/syslog

正常情况下的输出示例

  • iostat -x 输出示例
1
2
3
4
5
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
5.13 0.00 2.34 1.02 0.00 91.51

Device r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 2.00 1.00 0.20 0.10 64.00 0.00 3.00 1.00 0.30

说明:低iowait、低队列长度和较低的%util表明磁盘处于空闲状态。

  • dd 写入测试示例
1
2
3
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB) copied, 10.1 s, 106 MB/s
  • dd 读取测试示例
1
1073741824 bytes (1.1 GB) copied, 4.2 s, 256 MB/s
  • hdparm 测试示例
1
2
3
4
Timing cached reads:
12000 MB in 2.00 seconds = 6000.00 MB/sec
Timing buffered disk reads:
150 MB in 3.00 seconds = 50.00 MB/sec

注意事项

  • 数据备份:在进行磁盘调试和测试之前,请确保重要数据已经备份。
  • 测试环境:尽量在业务低峰期或非生产环境下进行性能测试,以免影响正常业务。
  • 挂载参数:检查磁盘挂载参数是否合理(如 noatime 选项)。
  • 负载影响:测试过程中关闭或暂停其它大IO操作,确保测试结果准确。
  • 硬件状态:若硬盘健康状态出现警告,建议及时更换硬盘以防数据丢失。

总结

通过上述步骤,你可以较为全面地排查Linux系统磁盘IO性能问题。从整体负载、iostat监控、dd测试到硬盘健康检查,各项指标正常时,系统读写性能应在预期范围内(例如机械硬盘写入速度在50-150 MB/s,SSD则更快)。如发现某项指标异常,则可进一步定位问题原因,例如硬件故障、系统配置问题或IO资源争用等。


Linux 磁盘IO读写性能排查指南
https://luffy997.github.io/2025/03/13/Linux-磁盘IO读写性能排查指南/
作者
Luffy997
发布于
2025年3月13日
许可协议