linux用很多可用的工具可以用來發現排錯,有些很容易使用,有些用法則比較高級
查看I/O wait問題不僅需要使用一些高級工具,也需要一些基本工具的高級用法。I/O wait之所以難以排查是因為默認有太多的工具告訴你系統I/O阻塞,但沒那么多工具可以幫你縮小范圍以便確定出是哪個或哪些進程引起的問題。
首先回答是不是I/O引起系統緩慢
確定是不是I/O引起系統緩慢,你可以使用很多工具但最簡單的還是unix命令top
[root@coolnull ~]# top top - 14:31:20 up 35 min, 4 users, load average: 2.25, 1.74, 1.68 Tasks: 71 total, 1 running, 70 sleeping, 0 stopped, 0 zombie Cpu(s): 2.3%us, 1.7%sy, 0.0%ni, 0.0%id, 96.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 245440k total, 241004k used, 4436k free, 496k buffers Swap: 409596k total, 5436k used, 404160k free, 182812k cached
從CPU(s) 這行你可以看出當前CPU I/O Wait的情況;越高的wa表示越多的cpu資源在等待I/O
wa -- iowait Amount of time the CPU has been waiting for I/O to complete. //cpu已經等待I/O完成的時間
查找哪個硬盤正在被寫入
上面的top命令從系統面大體展示了I/O Wait,但它沒有告訴你哪個硬盤正在被影響;為此我們需要使用iostat命令
[root@coolnull ~]# iostat -x 2 5 avg-cpu: %user %nice %system %iowait %steal %idle 3.66 0.00 47.64 48.69 0.00 0.00 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 44.50 39.27 117.28 29.32 11220.94 13126.70 332.17 65.77 462.79 9.80 2274.71 7.60 111.41 dm-0 0.00 0.00 83.25 9.95 10515.18 4295.29 317.84 57.01 648.54 16.73 5935.79 11.48 107.02 dm-1 0.00 0.00 57.07 40.84 228.27 163.35 8.00 93.84 979.61 13.94 2329.08 10.93 107.02
上述示例的iostat命令將每2秒打印出報告,共打印5次;-x參數告訴iostata打印出更詳盡的報告
iostat打印出的第1個報告,數值是基於最后一次系統啟動的時間統計的;基於這個原因,在大部份情況下,iostat打印出的第1個報告應該被忽略。每個子報告都是基於上1次的報告。在這個例子中,我們的命令將打印5次報告,第2份報告就是從第1份報告開始后的硬盤數據,第3份報告基於第2份,依此類推。
上述示例,sda盤的%utilized達到了111.41%。這表示引起I/O慢的進程在寫入sda盤。因為我這個測試實例中只有1個硬盤,但對於有多硬盤的服務器來說,這可以縮小在使用I/O的進程范圍。
除了iostat的%utilized能提供豐富的信息外,像rrqm/s、wrqm/s這些每秒讀、寫的請求數,r/s、w/s每秒讀寫數也很有用。在我們的例子中,我們的程序看起來讀寫很繁重的信息也能幫助我們確定這個討人厭的進程。
查找引起高I/O的進程
iotop
[root@coolnull ~]# iotop Total DISK READ: 8.00 M/s | Total DISK WRITE: 20.36 M/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 15758 be/4 root 7.99 M/s 8.01 M/s 0.00 % 61.97 % bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
查看哪個進程使用硬盤最多的最簡單的方法就是使用iotop命令。通過查看數據,我們很容易就能確定是bonnie++這個進程引起我們機器高I/O
雖然iotop好用,但默認主流的linux發行版中是沒有安裝的;並且我個人也不推薦依賴默認系統沒有安裝的命令。系統管理員總是會碰到這樣的情況,他們沒辦法在短時間內簡單地安裝這些非默認包。
如果iotop沒辦法用,以下的步聚還是可以幫助你縮小這些討人厭進程的范圍
進程狀態列表
ps命令能打印出內存,cpu的情況但沒辦法打印出硬盤I/O的情況。雖然ps沒辦法打印出I/O的情況,但它可以顯示出進程是否在等待I/O。
The ps state field provides the processes current state; below is a list of states from the man page.
ps狀態列提供了進程當前的狀態,以下從man ps上獲取的進程stat列表
PROCESS STATE CODES
D uninterruptible sleep (usually IO) R running or runnable (on run queue) S interruptible sleep (waiting for an event to complete) T stopped, either by a job control signal or because it is being traced. W paging (not valid since the 2.6.xx kernel) X dead (should never be seen) Z defunct ("zombie") process, terminated but not reaped by its parent.
等待I/O的進程通過處於uninterruptible sleep或D狀態;通過給出這些信息我們就可以簡單的查找出處在wait狀態的進程
示例:
[root@coolnull ~]# for x in `seq 1 1 10`; do ps -eo state,pid,cmd | grep "^D"; echo "----"; sleep 5; done D 248 [jbd2/dm-0-8] D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp ---- D 22 [kswapd0] D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp ---- D 22 [kswapd0] D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp ---- D 22 [kswapd0] D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp ---- D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp ----
上述命令會每5秒循環打印出位於D狀態的進程,共打印10次
從上面的輸出可以看出bonnie++,pid 16528比其它進程更加占用I/O。從這點,bonnie++看起來更有可能引起I/O Wait。但僅憑進程處於uninterruptible sleep state謄,還不能完全確定就是這引起的I/O wait。
為了幫助肯定我們的懷疑,我們可以使用/proc文件系統。在這個進程目錄里,每個進程都有一個io文件,里面的數值跟iotop命令獲取的I/O數值一樣。
[root@coolnull ~]# cat /proc/16528/io rchar: 48752567 wchar: 549961789 syscr: 5967 syscw: 67138 read_bytes: 49020928 write_bytes: 549961728 cancelled_write_bytes: 0
read_bytes和write_bytes就這個進程讀寫硬盤的字節數。在這里,bonnie++已經讀取了46MB,寫入524MB的數據。對很多進程,這可能不是很多,但在我們這個實例這足夠引起高i/o wait。
查找哪個文件在被繁重地寫入
lsof命令會為你展示指定進程打開的所有文件或依賴提供選項的所有進程。從這個列表,人們可以根據文件的大小和/proc io文件里出現的次數做出有用的猜測,哪個文件正在被頻繁地寫入。
為了減少輸出的內容,我們可以使用-p 選項來只打印指定進程id打開的文件
[root@coolnull ~]# lsof -p 16528 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bonnie++ 16528 root cwd DIR 252,0 4096 130597 /tmp <truncated> bonnie++ 16528 root 8u REG 252,0 501219328 131869 /tmp/Bonnie.16528 bonnie++ 16528 root 9u REG 252,0 501219328 131869 /tmp/Bonnie.16528 bonnie++ 16528 root 10u REG 252,0 501219328 131869 /tmp/Bonnie.16528 bonnie++ 16528 root 11u REG 252,0 501219328 131869 /tmp/Bonnie.16528 bonnie++ 16528 root 12u REG 252,0 501219328 131869 <strong>/tmp/Bonnie.16528
為了更進一步確認是這些文件被繁重地寫入,我們可以看下/tmp文件系統是不是sda盤的一部份。
[root@coolnull ~]# df /tmp Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/workstation-root 7667140 2628608 4653920 37% /
從df的輸出我們可以判斷出/tmp是根目錄下的一部份。
[root@coolnull ~]# pvdisplay --- Physical volume --- PV Name /dev/sda5 VG Name workstation PV Size 7.76 GiB / not usable 2.00 MiB Allocatable yes PE Size 4.00 MiB Total PE 1986 Free PE 8 Allocated PE 1978 PV UUID CLbABb-GcLB-l5z3-TCj3-IOK3-SQ2p-RDPW5S
使用pvdisplay我們可以看到硬盤sda的/dev/sda5分區就是workstation volume group在使用的分區也即是/tmp目錄。通過給出的信息就可以更安全地說上述losf命令列出來的大量文件很有可能就是正在被頻繁讀寫的文件。
轉載請注明:酷喃|coolnull| » 發現並解決linux高I/O Wait問題 – 如何發現linux中引起高io等待的進程
原文網址:http://coolnull.com/4444.html