Contents

如何在Linux系统中监视磁盘IO

1. 概述

在本教程中,我们将讨论如何监控 Linux 系统中的磁盘 I/O 活动。这是维护系统时要执行的一项重要任务。从本质上讲,从磁盘取回数据需要时间。因此,磁盘 I/O 子系统被认为是最慢的部分,并且会减慢整个系统的速度。

因此,检查磁盘性能很重要。我们需要查看是否存在瓶颈及其原因,并确定哪个进程正在等待 I/O 请求完成。为此,我们将学习如何使用iostatiotop sarvmstat 等工具来检查 Linux 系统中的磁盘 I/O 性能。

2. 安装工具

在我们开始之前,我们必须在我们的 Linux 系统中安装这些工具(如果它们尚不可用)。工具iostat、vmstatsarsysstat包的一部分。iotop工具是iotop包的一部分。

要在 Debian、Ubuntu 或任何其他衍生产品中安装,我们将运行:

$ sudo apt-get install sysstat
$ sudo apt-get install iotop

对于 RHLE、CentOS 和 Fedora,我们将运行:

$ sudo dnf install sysstat
$ sudo dnf install iotop

3. 报告磁盘 I/O 统计数据

首先,了解磁盘 I/O 活动的概况很有趣。在这种情况下,iostat命令非常方便且易于理解。它代表输入/输出统计。它报告有关 CPU 和磁盘设备利用率的信息。

目前,我们只关注磁盘 I/O 活动;因此,我们将使用*-d*选项:

$ iostat -d 
Linux 5.13.12-100.fc33.x86_64 (dhcppc5) 	08/30/2021 	_x86_64_	(4 CPU)
Device             tps    kB_read/s    kB_wrtn/s    kB_dscd/s    kB_read    kB_wrtn    kB_dscd
dm-0              4.84        48.24        35.44         0.00   15064145   11067448          0
dm-1              1.00         1.41         2.60         0.00     440364     812036          0
dm-2              0.18         5.59         0.01         0.00    1747005       2788          0
dm-3              0.08         8.02         0.58         0.00    2503710     180532          0
dm-4              0.00         0.00         0.00         0.00       1272          0          0
dm-5              0.08         8.02         0.58         0.00    2503421     181956          0
sda               3.14        63.31        38.14         0.00   19772796   11911070          0
scd0              0.00         0.00         0.00         0.00          1          0          0
zram0             7.74         9.36        21.58         0.00    2924188    6738944          0

要重复iostat命令,我们可以添加一个以秒为单位的间隔:

$ iostat -d 2

正如我们所见,iostat显示有关系统中存在的所有设备活动的信息。我们还可以添加*-p*选项来显示块设备及其所有分区的统计信息:

$ iostat -d -p sda
Device             tps    kB_read/s    kB_wrtn/s    kB_dscd/s    kB_read    kB_wrtn    kB_dscd
sda               4.11        78.09        47.02         0.00   77566501   46701318          0
sda1              0.00         0.01         0.00         0.00       8432          6          0
sda2              4.10        78.08        47.02         0.00   77550214   46701280          0
sda3              0.00         0.01         0.00         0.00       5168         32          0

默认情况下,iostat命令显示有关系统中存在的所有块设备和分区的信息。如果我们只想打印有关真正活动的磁盘或分区的信息,跳过指标为零的设备,我们可以添加*-z*选项:

$ iostat -d -z 2
Device             tps    kB_read/s    kB_wrtn/s    kB_dscd/s    kB_read    kB_wrtn    kB_dscd
dm-0              0.50         2.00         0.00         0.00          4          0          0
sda               0.50         2.00         0.00         0.00          4          0          0
zram0             2.50        10.00         0.00         0.00         20          0          0
Device             tps    kB_read/s    kB_wrtn/s    kB_dscd/s    kB_read    kB_wrtn    kB_dscd
dm-0             22.50         0.00       152.00         0.00          0        304          0
dm-3              0.50        64.00         0.00         0.00        128          0          0
dm-5              0.50        64.00         0.00         0.00        128          0          0
sda              16.00        64.00       148.00         0.00        128        296          0
zram0             0.50         2.00         0.00         0.00          4          0          0

4. 确定瓶颈背后的过程

我们之前讨论了如何检查 I/O 活动,但有时这还不够。例如,确定哪个进程或线程导致繁重的 I/O 活动很重要。iotop命令可以帮助我们做到这一点。它是一种交互式工具,可按进程或线程提供实时磁盘活动。请务必注意,iotop需要root权限或NET_ADMIN能力。

此外,我们必须检查是否启用了以下内核选项:

$ egrep '(CONFIG_VM_EVENT_COUNTERS|TASK_IO_ACCOUNTING|CONFIG_TASKSTATS|TASK_DELAY_ACCT)' /boot/config-$(uname -r)
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_VM_EVENT_COUNTERS=y

默认情况下,iotop命令显示每个进程或线程的磁盘 I/O 视图

$ sudo iotop
Total DISK READ :      18.27 K/s | Total DISK WRITE :       0.00 B/s
0.00 B DISK READ:      18.27 K/s | Actual DISK WRITE:      14.61 K/s
    TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
	
    509 be/3 root        0.00 B/s    0.00 B/s  0.00 %  3.91 % [jbd2/dm-0-8]
 247269 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.21 % [kworker/0:2-events]
   2507 be/4 nwd        18.27 K/s    0.00 B/s  3.57 %  0.00 % gnome-terminal-server
      1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % systemd --switched-root --system --deserialize 30
      2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
      3 be/0 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [rcu_gp]
      4 be/0 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [rcu_par_gp]
      6 be/0 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kworker/0:0H-events_highpri]
      9 be/0 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [mm_percpu_wq]
     10 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [rcu_tasks_kthre]
     11 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [rcu_tasks_rude_]
     12 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [rcu_tasks_trace]
     13 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [ksoftirqd/0]
     14 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [rcu_sched]

我们可以使用*-o*选项只显示实际执行 I/O 活动的进程或线程:

$ sudo iotop -o 
Total DISK READ :    1864.38 K/s | Total DISK WRITE :       0.00 B/s
10.34l DISK READ:    1875.65 K/s | Actual DISK WRITE:       0.00 B/s
    TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
	
 245778 be/4 nwd       608.93 K/s    0.00 B/s 62.08 % 34.04 % firefox -contentproc -childID 3 -isForBrowser -prefs~46 -appdir /usr/lib64/firefox/browser 245562 true tab
   1822 be/4 nwd       105.25 K/s    0.00 B/s  0.00 % 14.13 % gnome-shell
   2507 be/4 nwd       139.08 K/s    0.00 B/s  0.00 %  1.48 % gnome-terminal-server
 245562 be/4 nwd       206.74 K/s    0.00 B/s 93.98 %  0.00 % firefox
 246053ble_ponwd ]      18.79 K/s    0.00 B/s 24.22 %  0.00 % firefox -contentproc -childID 5 -isForBrowser -prefs~sr/lib64/firefox/browser 245562 true tab [DOM Worker]
 247924 be/4 nwd       127.80 K/s    0.00 B/s 44.84 %  0.00 % vlc --started-from-file /home/nwd/Music/Mozart Allegro assai.mp4
 247956 be/4 nwd       657.79 K/s    0.00 B/s 38.89 %  0.00 % dd if=/dev/zero of=/tmp/test.img bs=1G oflag=dsync

我们可以添加*-P*选项来显示没有线程的进程列表:

$sudo iotop -oP

5. 生成一段时间内的磁盘 I/O 统计信息

我们之前学习过如何实时监控磁盘活动,但有些情况下我们需要收集整整一周或更长时间的历史数据。目标是收集足够的数据用于分析或规划未来的发展。最简单的方法是使用sar命令。

默认情况下,sar命令监视所有系统资源。在我们的例子中,我们只对磁盘活动感兴趣。让我们使用*-b*选项来报告有关磁盘活动的详细信息:

$ sar -b 1 
...
04:10:00 PM       tps      rtps      wtps      dtps   bread/s   bwrtn/s   bdscd/s
04:10:01 PM     12.00      0.00     12.00      0.00      0.00    176.00      0.00
04:10:02 PM     35.00     31.00      4.00      0.00   1272.00     80.00      0.00
04:10:03 PM      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:10:04 PM     73.00      0.00     73.00      0.00      0.00    648.00      0.00
04:10:05 PM      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:10:06 PM     22.00      0.00     22.00      0.00      0.00    192.00      0.00
04:10:07 PM      1.00      0.00      1.00      0.00      0.00      8.00      0.00
04:10:08 PM      4.00      0.00      4.00      0.00      0.00    112.00      0.00

我们可以使用*-d选项报告每个块设备的活动。我们还可以使用-p*选项轻松识别设备:

$ sar -p -d -b 1
04:26:15 PM       DEV       tps     rkB/s     wkB/s     dkB/s   areq-sz    aqu-sz     await     %util
04:26:16 PM       sda      2.00    128.00     52.00      0.00     90.00      0.00      0.50      0.40
04:26:16 PM       sr0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:26:16 PM   lv-root      1.00      0.00     52.00      0.00     52.00      0.00      1.00      0.20
04:26:16 PM   lv-swap      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:26:16 PM     zram0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
04:26:16 PM   lv-home      1.00    128.00      0.00      0.00    128.00      0.00      1.00      0.20
...

可以使用*-o选项将sar*命令的输出保存在文件中。请注意,该文件是二进制格式:

$ sar 2 5 -o /tmp/data_io > /dev/null 2>&1

现在我们将使用*-f选项来读取保存在文件中的sar*命令生成的报告:

$ sar -f /tmp/data_io

6. 使用vmstat测量磁盘 I/O 使用情况

另一个有用的工具是vmstat,它提供了系统中正在发生的事情的总体视图。例如,我们可以使用vmstat命令来报告有关进程、内存和 CPU 的信息,并显示磁盘 I/O 活动。

要使用vmstat从系统检索磁盘 I/O 统计信息,我们调用:

$ vmstat [-D] [-d] [-p partition] [interval [count]]

我们将使用*-d*选项来显示单个磁盘统计信息:

$ vmstat -d 1
isk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors      ms  total merged sectors      ms    cur    sec
sda   2659118 1531393 166084689 49623955 1725402 4672072 104580917 70770454      0  25194
sr0    24187     28 5886957 1315209      0      0       0       0      0    966
dm-0  2178560      0 114338954 50785360 3433060      0 81458000 79180110      0  21302
dm-1  1605211      0 12845592 24735782 2946339      0 23570712 947720915      0   5866
zram0 2609461      0 20875688   26812 4958733      0 39669864   57039      0    511
dm-2  312586      0 21187074 3814922   2852      0   49288   76928      0    674
dm-3   88452      0 17673344  640177   4957      0  526864  104362      0    537
...

然后我们将引入*-p*选项来获取有关分区的详细性能统计信息:

$ vmstat -p /dev/sda2 1 
sda2            reads      read sectors      writes  requested writes
              2663617         166204812     1725915         104595152
              2663617         166204812     1725915         104595152
              2663617         166204812     1725915         104595152
              2663618         166205068     1725915         104595152
              2663618         166205068     1725917         104595216
...