一篇學會 IO 問題排查
一 背景
IO性能排查,只要工具齊全,按照套路排查,相對來說還是比較容易查的。
二 一般步驟
2.1 預覽io性能是否有問題
先通過top命令,檢查wa的cpu是否占用高,如果高,那就需要排查哪個進程引起的IO問題了,是否合理。
一般來說還習慣先用df -h 和df -ih排查下磁盤空間是否占滿,inode節(jié)點是否占滿。
iostat 進行普遍的磁盤性能觀測,如下:
[root@localhost ~]# iostat -x -d 1
Linux 4.18.0-348.2.1.el8_5.x86_64 (localhost.localdomain) 2021年12月07日 _x86_64_ (8 CPU)
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
sda 5.81 1.22 309.14 101.03 0.08 0.37 1.39 23.45 19.39 3.88 0.12 53.21 82.55 4.62 3.25
scd0 0.03 0.00 0.70 0.00 0.00 0.00 0.00 0.00 9.97 0.00 0.00 26.24 0.00 10.15 0.03
scd1 0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.22 0.00 0.00 0.17 0.00 0.89 0.00
dm-0 5.56 1.53 290.23 77.20 0.00 0.00 0.00 0.00 19.87 1.72 0.11 52.16 50.33 4.51 3.20
dm-1 0.07 0.00 1.49 0.00 0.00 0.00 0.00 0.00 0.88 0.00 0.00 22.65 0.00 0.89 0.01
解釋:
r/s : 每秒發(fā)送給此磁盤的合并后讀請求數(shù)量。
w/s : 每秒發(fā)送給此磁盤的合并后寫請求數(shù)量。
rkB/s : 每秒從磁盤讀取的數(shù)據(jù)量,單位是KB。
wkB/s: 每秒向此磁盤寫入的數(shù)據(jù)量,單位是KB。
rrqm/s : 每秒合并的讀請求數(shù);加上%標識合并的讀請求的百分比。
wrqm/s : 每秒合并的寫請求數(shù);加上%標識合并的寫請求的百分比。
r_await:平均每個讀請求處理的平均時長,單位為ms,包括排隊時間和實際磁盤處理時間。
w_await: 平均每個寫請求處理的平均時長,單位為ms,包括排隊時間和實際磁盤處理時間。
aqu-sz: 平均請求隊列的長度
rareq-sz :平均讀請求大小,單位為KB。
wareq-sz: 平均寫請求大小,單位為KB。
svctm:處理IO請求的平均時間,不包括等待時間,不可信尷尬。
%util : 向設備發(fā)出I/O請求所占用的時間百分比(設備的帶寬利用率)。當該值為時,設備飽和,串行服務的設備,接近100%,對于并行請求,并不能反應磁盤設備極限。
其實man iostat 看的就比較清楚了,寫下來,只是為了記憶一遍,加深點印象。 說明:
- r/s+ w/s ,就是 IOPS;
- %util ,就是我們前面提到的磁盤 I/O 使用率;
- rkB/s+wkB/s ,就是吞吐量;
- r_await+w_await ,就是響應時間。
2.2 定位具體的IO大的任務
iostat 看整體性能是否達到了瓶頸,我們要排查具體哪個程序占用IO比較大,采用pidstat命令:
[root@localhost ~]# pidstat -d 1
Linux 4.18.0-305.3.1.el8.x86_64 (localhost.localdomain) 12/07/2021 _x86_64_ (56 CPU)
09:46:06 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
09:46:07 PM 0 4597 0.00 1502.91 0.00 0 xxxx
解釋:
UID : 用戶ID
PID : 進程ID
kB_rd/s : 每秒讀取的數(shù)據(jù)大小 單位是 KB。
kB_wr/s: 每秒寫的數(shù)據(jù)大小 單位是KB。
kB_ccwr/s: 每秒取消寫請求數(shù)量大小,單位是KB。
iodelay :塊IO延遲,包括同步塊IO和換入塊時間,單位為時鐘周期
還可以通過iotop查看IO使用的排行,非常方便:
08:59:08 Total DISK READ : 0.00 B/s | Total DISK WRITE : 0.00 B/s
08:59:08 Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s
TIME TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
b'08:59:08 1 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % systemd --switched-root --system --deserialize 18'
b'08:59:08 2 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kthreadd]'
centos有的版本需要單獨安裝:
yum install iotop
2.3 strace進行追蹤
strace是跟蹤用戶空間的進程的系統(tǒng)調(diào)用和信號傳遞的,非常給力。
# 比較簡單的方式,-f會追蹤fork,或其線程。
strace -pf pid
# 更給力的
strace -tt -T -v -f -e trace=file -o /data/log/strace.log -s 1024 -p 23489
-tt 顯示毫秒時間
-T 顯示每次調(diào)用的花費
-v 把調(diào)用環(huán)境變量也打印出來,
-f 跟蹤目標進程包括所有子進程
-e 控制跟蹤的事件和行為 file文件行為,process跟蹤進程和進程管理相關的系統(tǒng)調(diào)用,ipc跟蹤ipc通信的系統(tǒng)調(diào)用;network 跟蹤網(wǎng)絡相關系統(tǒng)調(diào)用;signal 跟蹤信號處理相關系統(tǒng)調(diào)用;desc 跟蹤文件描述符相關系統(tǒng)調(diào)用
-o 輸出到文件
-s 參數(shù)最長字符串,1024
2.4 給力的filetop
linux 內(nèi)核在4.1以上版本的內(nèi)核支持bcc工具集合,這個工具集非常有用,比如這個filetop,查看具體文件的IO大小,如下:
[root@localhost tools]# ./filetop -C
Tracing... Output every 1 secs. Hit Ctrl-C to end
09:39:02 loadavg: 0.07 0.06 0.01 1/280 10779
TID COMM READS WRITES R_Kb W_Kb T FILE
10779 filetop 2 0 15 0 R loadavg
10779 filetop 1 0 4 0 R type
10779 filetop 1 0 4 0 R retprobe
10779 filetop 2 0 0 0 R _bootlocale.cpython-36.pyc
分別對應:tid線程id,comm 線程命令行, READS WRITES 讀寫次數(shù), R_Kb W_Kb 讀寫大小,T文件類型 FILE: 文件名。
centos安裝:
yum install bcc-tools
export PATH=$PATH:/usr/share/bcc/tools
三 額外bcc工具
3.1 execsnoop
這個也是bcc工具集合里面的工具,通過 ftrace 實時監(jiān)控進程的 exec() 行為,并輸出短時進程的基本信息,對于一些奇怪的短時進程的查找非常有幫助。
[root@localhost tools]# ./execsnoop
PCOMM PID PPID RET ARGS
dmsetup 11391 1787 0 /usr/sbin/dmsetup status --target thin-pool
pmie_check 11406 1 0 /usr/libexec/pcp/bin/pmie_check -C
sed 11408 11407 0 /usr/bin/sed -e s/"http://g /etc/pcp.conf
awk 11409 11407 0 /usr/bin/awk -F= \n/^PCP_/ && NF == 2 {\n exports=exports" "$1\n printf "%s=${%s:-\"%s\"}\n", $1, $1, $2\n }\nEND { print "export", exports }
3.2 opensnoop
opensnoop通過追蹤open()系統(tǒng)調(diào)用顯示企圖打開文件的進程,可以用于定位配置文件或日志文件,有些場合用起來還是挺順手的。
[root@localhost tools]# ./opensnoop
PID COMM FD ERR PATH
1075 tuned 21 0 /proc/11378/cmdline
1075 tuned 21 0 /proc/11378/stat
1023 irqbalance 6 0 /proc/interrupts
1023 irqbalance 6 0 /proc/stat
1023 irqbalance 6 0 /proc/irq/15/smp_affinity
1023 irqbalance 6 0 /proc/irq/15/smp_affinity
1685 pmdaproc 7 0 /proc
1685 pmdaproc 7 0 /proc/11375/cmdline