使用top查看系统资源使用情况,查看到cpu使用率较高,其中iowait很高,说明有进程在iowait上消耗很多资源,但是,通过top又没有办法定位是哪个进程搞得鬼,因此需要借助其他工具 iotop及通过一
些定位流程来确定是谁用了我的cpu。
iowait
“iowait” 是指系统中等待 I/O(Input/Output)操作完成的时间,通常以百分比表示。在Linux和类Unix系统中,iowait 是 top 和其他系统性能监控工具中的一个关键性能指标之一。
I/O 操作包括磁盘读写、网络传输等。当进程发出一个 I/O 请求(例如,从磁盘读取文件或从网络接收数据)后,它通常需要等待底层硬件设备或网络传输完成。这个等待过程就被称为 iowait。
高 iowait 百分比通常表示以下情况之一:
- 磁盘繁忙:磁盘可能正在执行大量读写操作,因此新的 I/O 请求必须等待。
- 磁盘故障:磁盘上的某些问题可能导致 I/O 操作的延迟或失败,从而增加了 iowait。
- 网络延迟:在涉及网络 I/O 的情况下,iowait 可能会增加,因为网络通信可能需要更长时间。
- 过多的 I/O 请求:系统上运行的进程过多,发出了大量的 I/O 请求,导致 I/O 队列堆积,从而增加了 iowait 时间。
iotop
iotop :查看各个进程iowait使用率的工具(我所使用的iotop使用c编写,单bin文件,编译方便,便于移植)
源码连接:iotop Ubuntu 18.04 x86:iotop x86版本 Ubuntu 18.04 arm:iotop arm版本
使用iotop排查IO占用高的流程:
- 定位线程ID: iotop查看占用高的TID
- 定位PID: 通过TID查PID,
ps -eLf | grep <TID>
一般在COMMAD可以看到命令行信息 - 定位程序细节: 通过
lsof -p <PID>
查看进程打开的文件
排查流程
创建一个高io的进程
$ dd if=/dev/zero of=zero.txt bs=1M count=16000
查看系统资源占用top -d 1
, 看可以看到 io有38.2%(io前的数字)的占用率。
Mem: 7748992K used, 140140K free, 654804K shrd, 108K buff, 6572532K cached
CPU: 0.5% usr 1.2% sys 0.5% nic 59.5% idle 38.2% io 0.0% irq 0.0% sirq
Load average: 1.80 0.65 0.33 1/211 32109
PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND
31975 31938 root D 9868 0.1 1 1.3 /bin/dd if /dev/zero of zero.txt bs 1M count 16000
31974 28743 root S 23352 0.3 3 0.2 ./iotop
31956 28720 root R 8840 0.1 2 0.1 top -d 1
526 2 root SW 0 0.0 0 0.1 [kworker/0:1]
557 2 root SW 0 0.0 0 0.1 [kswapd0]
24953 2 root DW 0 0.0 1 0.1 [kworker/u8:1]
定位线程ID
运行iotop
, 可以看到dd
和kworker/u8:1
占用率最高,分别对应TID为:24953 和 31975 ,其中kworker为操作系统调用的进程。由于iotop展示的是TID,为线程ID,需要查看对应的进程ID。
$ sudo iotop
-----------------------------------------------------------------------------------------------------------------------------
Total DISK READ: 0.00 B/s | Total DISK WRITE: 102.26 M/s
Current DISK READ: 0.00 B/s | Current DISK WRITE: 93.85 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO GRAPH[IO]> COMMAND
24953 be/4 root 0.00 B/s 0.00 B/s 0.00 % 100.00 % |||||||||||||| kworker/u8:1
31975 be/4 root 102.26 M/s 0.00 B/s 0.00 % 84.76 % |||||||||||||| dd
''''
5 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % kworker/0:0H
定位PID
查看TID对应的PID,可以看到已经定位是/bin/dd if /dev/zero of zero.txt bs 1M count 16000
命令行导致的io占用率过高。
$ ps -eLf | grep 31975
root 31975 31938 31975 26 1 18:49 pts/10 00:00:08 /bin/dd if /dev/zero of zero.txt bs 1M count 16000
定位程序细节
但对于复杂进程,如别人写的代码(如开源代码)可能需要确定哪部分代码出现的问题,以便修复bug,需要查找更多线索,可以通过lsof -p <PID>
查看是进程都打开了哪些文件,当然这里指的文件是广义的linux中文件(万物皆文件)。可以看到FD的状态,是读(r)还是写(w)。
$ lsof -p 31975
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
dd 31975 root rtd DIR 0,16 480 464 /
dd 31975 root txt REG 0,16 2963120 547 /bin/busybox
dd 31975 root mem REG 0,16 5776816 28934 /usr/lib/locale/locale-archive
dd 31975 root 0r CHR 1,5 0t0 6213 /dev/zero
dd 31975 root 1w REG 8,16 6023487488 551481 /tmp/zero.txt
dd 31975 root 2u CHR 136,10 0t0 13 /dev/pts/10
当然存在一些 文件只有 NODE 没有 NAME ,可以通过stat
查看状态。