如果Linux服务器I/O负载过高,会导致生产环境服务无法工作,严重时SSH登录很慢,导致排障时间增加。
这个时候尽快定位并解决问题显得尤为重要。合适的排错路径会事半功倍。
本文使用系统自带的【top/ps】命令和需要安装的【iostat、iotop】进行排查。
安装命令如下1
2# sudo apt install sysstat
# sudo apt install iotop-c模拟故障:使用下面的命令模拟磁盘的大量写入
1
# dd if=/dev/zero of=/tmp/largefile bs=1M count=10240 oflag=direct
top 命令确认是否是I/O负载问题
【wa】值是指 CPU 处于空闲状态但等待磁盘或其他外部 I/O 操作(如网络 I/O)完成的时间比例。高【wa】值(较高的百分比):表示系统存在 I/O 瓶颈。1
2
3
4
5
6
7
8
9
10
11# top
top - 05:06:58 up 68 days, 1:44, 3 users, load average: 0.65, 0.19, 0.06
Tasks: 208 total, 1 running, 207 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.3 sy, 0.0 ni, 49.8 id, 49.9 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3915.6 total, 315.7 free, 742.2 used, 3160.3 buff/cache
MiB Swap: 3915.0 total, 3914.7 free, 0.2 used. 3173.4 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3905352 root 20 0 15224 7860 5760 S 0.3 0.2 0:02.33 sshd
3946974 root 20 0 12072 6016 3712 R 0.3 0.2 0:00.02 top
1 root 20 0 22700 14080 9728 S 0.0 0.4 1:18.21 systemdiostat -x 2 3 命令查看磁盘I/O使用率
此命令按照2秒的间隔统计3次I/O数据,后两组数据代表最新的状态。
【%util】列的值表示设备的使用率,即设备在处理 I/O 请求时被忙占用的时间百分比。
此处sda磁盘使用率比较高,I/O瓶颈。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# iostat -x 2 3
Linux 6.8.0-36-generic (ubuntu24) 09/11/2024 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.04 0.00 0.05 1.18 0.00 98.73
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
dm-0 0.01 0.15 0.00 0.00 27.85 19.60 1.30 9.59 0.00 0.00 185.30 7.36 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.24 3.32
loop0 0.00 0.00 0.00 0.00 0.00 1.27 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 0.00
sda 0.01 0.26 0.00 18.33 28.32 33.09 0.71 9.68 0.60 45.65 181.64 13.62 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.13 3.33
avg-cpu: %user %nice %system %iowait %steal %idle
0.00 0.00 0.00 50.13 0.00 49.87
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 4.50 4608.00 0.00 0.00 205.89 1024.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.93 100.00
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 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 9.00 4608.00 0.00 0.00 206.00 512.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.85 100.00
avg-cpu: %user %nice %system %iowait %steal %idle
0.00 0.00 0.25 57.79 0.00 41.96
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 9.50 5648.00 0.00 0.00 184.37 594.53 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.75 100.00
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 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 12.00 5648.00 3.00 20.00 174.04 470.67 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.09 100.00iotop 命令查看当前进程中的高I/O命令和进程ID
此处 3949828 的进程磁盘写入很高。1
2
3
4
5
6# iotop
Total DISK READ: 0.00 B/s ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | Total DISK WRITE: 2033.76 K/s ⣶⣤⣶⣾⣴⣶⣶⣦⣾⣦⣶⣶⣴⣶⣴⣶⣴⣶⣶⣶⣶⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
Current DISK READ: 0.00 B/s ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | Current DISK WRITE: 2033.76 K/s ⣶⣤⣶⣾⣴⣶⣶⣦⣾⣦⣶⣶⣴⣶⣴⣶⣴⣶⣶⣶⣶⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
TID PRIO USER DISK READ DISK WRITE GRAPH[R+W]▽ COMMAND [T](05:15:31)
3949828 be/4 root 0.00 B/s 2033.76 K/s ⣶⣤⣶⣾⣴⣶⣶⣦⣾⣦⣶⣶⣴⣶⣴⣶⣴⣶⣶⣶⣶⠀⠀⠀dd ▲
3748947 be/4 root 0.00 B/s 0.00 B/s ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀emd-journald如果没有安装 iotop,可使用ps命令过滤进程状态为D的进程,然后查看PID的磁盘读写状态
在 Linux 系统中,进程状态为 D 代表 不可中断的睡眠状态(Uninterruptible Sleep)。
这意味着进程正在等待一个无法中断的系统事件,通常是与 I/O 相关的操作,例如等待磁盘或网络 I/O 完成。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# for x in `seq 1 1 3`; do ps -eo state,pid,cmd | grep "^D"; echo "----"; sleep 3; done
D 3953121 dd if=/dev/zero of=/tmp/largefile bs=1M count=10240 oflag=direct
----
D 3953121 dd if=/dev/zero of=/tmp/largefile bs=1M count=10240 oflag=direct
----
D 3953121 dd if=/dev/zero of=/tmp/largefile bs=1M count=10240 oflag=direct
----
# cat /proc/3953121/io
rchar: 1120934832
wchar: 1119879168
syscr: 1080
syscw: 1068
read_bytes: 0
write_bytes: 1120927744
cancelled_write_bytes: 0
最后可以针对实际情况,优化任务或者紧急时停用进程。