iowait 分析

对于iowait升高的问题,首先要查询系统i/o情况,使用dstat工具可以同时查看cpu和i/o这两种资源的使用情况 步骤1.dstat分析

1
2
3
4
5
6
7
8
# 间隔 1 秒输出 10 组数据
$ dstat 1 10
# 打印
You did not select any stats, using -cdngy by default.
--total-cpu-usage-- -dsk/total- -net/total- ---paging-- ---system-- 
usr sys idl wai stl| read  writ| recv send| in out | int csw  
  0   0 96   4   0| 1219k 408k|   0     0|  0   0| 42  885 
  0   0 2   98   0|   34M   0| 198B  790B|  0   0| 42  138

分析:当iowait升高时,磁盘的读请求(read)都很大

步骤2.用top分析

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 观察一段时间
$ top
# 打印
PID USER 4340 root 4345 root 4344 root
...
PID USER  PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
4340 root 20 0 44676 4048 3432 R 0.3 0.0 0:00.05 top
4345 root 20 0 37280 33624 860 D 0.3 0.0 0:00.01 app
4344 root 20 0 37280 33624 860 D 0.3 0.4 0:00.01 app
...

分析:发现D状态的进程

步骤3.pidstat

用pidstat分析D状态的进程;输出:kB_rd 表示每秒读的 KB 数, kB_wr 表示每秒写的 KB 数,iodelay 表示 I/O 的延迟(单位是时钟周期)

1
2
# -d 展示 I/O 统计数据,-p 指定进程号,间隔 1 秒输出 3 组数据
$ pidstat -d -p <pid> 1 3

如果没有发现读写数大的进程,说明可能是其他进程导致的

1
2
3
4
5
6
7
8
# 间隔 1 秒输出多组数据 (这里是 20 组)
$ pidstat -d  1 20
# 打印
...
06:48:52 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command 
06:48:53 0  6083 32768.00   0.00    0.00     105    app
06:48:53 0  6084 32768.00   0.00    0.00     105    app
...

分析:找到app进程中,存在每秒32MB的读数据

步骤4.分析pid进程问题 1.strace -p 2.ps aux | grep 3.perf工具

1
2
$ perf record -g
$ perf report

僵尸进程

要解决掉它们,就要找到它们的根儿,也就是找出父进程,然后在父 进程里解决。

1
2
3
4
# -a 表示输出命令行选项
# p 表 PID
# s 表示指定进程的父进程
$ pstree -aps 3084

通过进程树找到父进程,然后修改代码问题。