Linux 系统的性能不仅受到 CPU、内存等的影响,也会收到硬盘读写的影响。当硬盘读写频繁时,往往导致系统操作卡顿、延迟等。本篇以 Ubuntu 18.04/Debian 10 为例介绍如何查看 Linux 系统硬盘读写情况。

命令安装

查看 Ubuntu 系统的硬盘读写常用命令有 sar, iostat, vmstat 等。安装命令如下:

1
2
sudo apt update
sudo apt install sysstat

CentOS 安装方法如下:

1
sudo yum install -y sysstat

sar -d

sar 命令能够 Collect, report, or save system activity information,在统计硬盘读写时,可以使用 -d 参数,Report activity for each block device.

格式如下:

1
sar -d interval count
  • interval 表示两次统计之间的间隔,单位为秒
  • count 表示统计次数

如下命令,没 2 秒统计一次,共统计 3 次

1
sar -d 2 3

输出结果为

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Linux 5.4.0-105-generic (jinzhongxu-PowerEdge)     2022年03月30日  _x86_64_        (360 CPU)

20时59分31秒 DEV tps rkB/s wkB/s areq-sz aqu-sz await svctm %util
20时59分33秒 dev7-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分33秒 dev7-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分33秒 dev7-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分33秒 dev7-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分33秒 dev7-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分33秒 dev7-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分33秒 dev7-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分33秒 dev7-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分33秒 dev8-0 277.50 5822.00 244.00 21.86 9.25 35.13 3.50 97.20

20时59分33秒 DEV tps rkB/s wkB/s areq-sz aqu-sz await svctm %util
20时59分35秒 dev7-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分35秒 dev7-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分35秒 dev7-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分35秒 dev7-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分35秒 dev7-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分35秒 dev7-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分35秒 dev7-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分35秒 dev7-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分35秒 dev8-0 363.50 4764.00 1110.00 16.16 18.53 52.69 2.56 93.00

20时59分35秒 DEV tps rkB/s wkB/s areq-sz aqu-sz await svctm %util
20时59分37秒 dev7-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分37秒 dev7-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分37秒 dev7-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分37秒 dev7-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分37秒 dev7-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分37秒 dev7-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分37秒 dev7-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分37秒 dev7-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时59分37秒 dev8-0 404.50 3398.00 1366.00 11.78 20.93 53.11 2.31 93.60

Average: DEV tps rkB/s wkB/s areq-sz aqu-sz await svctm %util
Average: dev7-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: dev7-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: dev7-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: dev7-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: dev7-4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: dev7-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: dev7-6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: dev7-7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: dev8-0 348.50 4661.33 906.67 15.98 16.24 48.19 2.71 94.60

针对统计信息,判读如下:

  • 一般情况下,svctm(倒数第二列)的取值与硬盘的性能有关系,通常会小于 awarit(倒数第三列)。但 CPU、内存会对 svctm 造成影响,过多的请求会间接导致 svctm 值得增加;
  • await 的值通常会受 svctm、I/O 队列以及请求模式影响,如果 svctm 和 await 接近,则表示几乎没有 I/O 等待,当前硬盘的性能很好;当 await 的值远高于 svctm,则表示 I/O 队列等待太长,系统上运行的应用程序将变慢,可以考虑更换更快的硬盘来解决;
  • %util 的值越接近 100%,表示硬盘产生的 I/O 请求越多,负荷越大,长期高负荷将影响系统性能。

iostat -d

sar -d 命令相同,iostat -d 也能够查看系统的硬盘使用情况。两者的命令格式相同。

  • -c 显示CPU使用情况
  • -d 显示磁盘使用情况
  • -k 以K为单位显示
  • -m 以M为单位显示
  • -N 显示磁盘阵列(LVM) 信息
  • -n 显示NFS使用情况
  • -p 可以报告出每块磁盘的每个分区的使用情况
  • -t 显示终端和CPU的信息
  • -x 显示详细信息

示例如下:

1
iostat -d 2 3

输出结果如下:

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
27
28
29
30
31
32
33
34
Linux 5.4.0-105-generic (jinzhongxu-PowerEdge)     2022年03月31日  _x86_64_        (360 CPU)

Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
loop0 0.00 0.00 0.00 531 0
loop1 0.00 0.00 0.00 46 0
loop2 0.00 0.00 0.00 1058 0
loop3 0.00 0.00 0.00 1071 0
loop4 0.00 0.00 0.00 1175 0
loop5 0.00 0.00 0.00 76 0
loop6 0.00 0.00 0.00 148 0
loop7 0.00 0.00 0.00 80 0
sda 21.27 125.13 276.74 92891793 205441296

Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
loop0 0.00 0.00 0.00 0 0
loop1 0.00 0.00 0.00 0 0
loop2 0.00 0.00 0.00 0 0
loop3 0.00 0.00 0.00 0 0
loop4 0.00 0.00 0.00 0 0
loop5 0.00 0.00 0.00 0 0
loop6 0.00 0.00 0.00 0 0
loop7 0.00 0.00 0.00 0 0
sda 3.50 4.00 30.00 8 60

Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
loop0 0.00 0.00 0.00 0 0
loop1 0.00 0.00 0.00 0 0
loop2 0.00 0.00 0.00 0 0
loop3 0.00 0.00 0.00 0 0
loop4 0.00 0.00 0.00 0 0
loop5 0.00 0.00 0.00 0 0
loop6 0.00 0.00 0.00 0 0
loop7 0.00 0.00 0.00 0 0
sda 9.50 2.00 86.00 4 172

注意:结果中第一次的输出是系统从启动以来直到统计时所有统计信息,从第二次输出才表示指定时间段内的数据。

  • tps 表示每秒向设备发出的传输(I/O请求)次数;
  • kB_read/s 表示从设备读取的数据量,以每秒块数(千字节、兆字节)表示。 块相当于扇区,因此大小为 512 字节;
  • kB_wrtn/s 表示写入设备的数据量,以每秒块数(千字节、兆字节)表示;
  • kB_read 表示读取的块总数(千字节、兆字节);
  • kB_wrtn 表示写入的块总数(千字节、兆字节)。

对上面各指标的解读。

  1. 当 kB_read/s 较大时,表示当前硬盘的读操作频繁;
  2. 当 kB_wrtn/s 较大时,表示当前硬盘的写操作频繁;
  3. kB_read 和 kB_wrtn 没有固定限制,不同系统范围不同。

当只关心某一个硬盘的 I/O 情况时,可以使用 -x 参数。示例如下:

1
2
3
4
5
6
7
8
9
10
# 打印所有硬盘
df -h
# 结果如下
Filesystem Size Used Avail Use% Mounted on
udev 47G 0 47G 0% /dev
tmpfs 9.3G 2.6M 9.3G 1% /run
/dev/sda1 500T 376T 145T 73% /

# 查看指定硬盘
iostat -x /dev/sda1 2 3

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Linux 5.4.0-105-generic (jinzhongxu-PowerEdge)     2022年03月31日  _x86_64_        (360 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
1.15 0.08 0.25 0.32 0.00 98.20

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
sda1 5.18 16.07 124.95 276.67 1.18 7.84 18.52 32.77 50.20 19.76 0.54 24.11 17.21 5.17 10.99

avg-cpu: %user %nice %system %iowait %steal %idle
1.69 0.27 0.07 0.10 0.00 97.87

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
sda1 0.00 10.50 0.00 96.00 0.00 7.50 0.00 41.67 0.00 6.86 0.06 0.00 9.14 7.81 8.20

avg-cpu: %user %nice %system %iowait %steal %idle
1.69 0.26 0.06 0.28 0.00 97.70

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
sda1 0.50 80.50 2.00 1936.00 0.00 7.50 0.00 8.52 5.00 12.93 0.91 4.00 24.05 2.42 19.60

输出结果基本和 sar -d 命令的输出结果相同,需要额外说明的几个选项的含义如下:

  • rrqm/s:表示每秒被合并的读操作数目(文件系统会对读取同一 block 块的请求进行合并);
  • wrqm/s:表示每秒被合并的写操作数目;
  • r/s:表示每秒完成读 I/O 设备的次数;
  • w/s:表示每秒完成写 I/O 设备的次数;
  • rsec/s:表示每秒读取的扇区数;
  • wsec/s:表示每秒写入的扇区数。

vmstat -d

命令 vmstat -d 格式与上面两个命令相似,示例如下:

1
vmstat -d 2 3

输出结果如下:

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
27
28
29
30
31
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
loop0 236 0 1062 955 0 0 0 0 0 0
loop1 19 0 92 244 0 0 0 0 0 0
loop2 73 0 2116 1456 0 0 0 0 0 0
loop3 76 0 2142 648 0 0 0 0 0 0
loop4 158 0 2350 989 0 0 0 0 0 0
loop5 49 0 152 1621 0 0 0 0 0 1
loop6 73 0 296 969 0 0 0 0 0 0
loop7 53 0 160 594 0 0 0 0 0 0
sda 3853838 875611 185790298 193401555 11949081 5824509 411333008 236054326 0 81684
loop0 236 0 1062 955 0 0 0 0 0 0
loop1 19 0 92 244 0 0 0 0 0 0
loop2 73 0 2116 1456 0 0 0 0 0 0
loop3 76 0 2142 648 0 0 0 0 0 0
loop4 158 0 2350 989 0 0 0 0 0 0
loop5 49 0 152 1621 0 0 0 0 0 1
loop6 73 0 296 969 0 0 0 0 0 0
loop7 53 0 160 594 0 0 0 0 0 0
sda 3853838 875611 185790298 193401555 11949118 5824523 411334008 236054595 0 81684
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
loop0 236 0 1062 955 0 0 0 0 0 0
loop1 19 0 92 244 0 0 0 0 0 0
loop2 73 0 2116 1456 0 0 0 0 0 0
loop3 76 0 2142 648 0 0 0 0 0 0
loop4 158 0 2350 989 0 0 0 0 0 0
loop5 49 0 152 1621 0 0 0 0 0 1
loop6 73 0 296 969 0 0 0 0 0 0
loop7 53 0 160 594 0 0 0 0 0 0
sda 3853838 875611 185790298 193401555 11949138 5824530 411334432 236054742 0 81684

vmstat 主要是报告虚拟内存统计信息,但是,增加 -d 参数后也能够统计硬盘情况。除此之外,vmstat 还报告有关进程、内存、分页、块 IO、陷阱、磁盘和 cpu 活动的信息。

关于上面介绍命令的更多使用情况,可以使用 man、help 等查看。

pidstat -d

该命令能够一直展示 I/O 统计,同时,包含有进程 pid, 如下命令表示每秒钟展示一次。使用 ctrl + c 结束统计。

1
pidstat -d 1

iotop 查看占用 I/O 高的进程

上面的命令帮助我们查看当前磁盘的使用情况,那么当磁盘因为某个进程导致 I/O 较大时,如何关闭进程呢?首先我们需要通过 iotop 命令查看哪些进程占用的 I/O 最大,然后,通过命令 kill pid 杀死该进程。

1
sudo iotop -oP
  • -o 表示仅显示实际执行 I/O 的进程或线程,而不是显示所有进程或线程。 这可以通过按 o 动态切换。
  • -P 表示只显示进程。 通常 iotop 显示所有线程。

参考文献

  1. Linux查看硬盘读写情况(汇总版)
  2. Linux 查看磁盘IO并找出占用IO读写很高的进程
  3. Linux iostat命令详解