linux 系統(tǒng)監(jiān)控、診斷工具之 IO wait
1、問題:
最近在做日志的實(shí)時(shí)同步,上線之前是做過單份線上日志壓力測試的,消息隊(duì)列和客戶端、本機(jī)都沒問題,但是沒想到上了第二份日志之后,問題來了:
集群中的某臺(tái)機(jī)器 top 看到負(fù)載巨高,集群中的機(jī)器硬件配置一樣,部署的軟件都一樣,卻單單這一臺(tái)負(fù)載有問題,初步猜測可能硬件有問題了。
同時(shí),我們還需要把負(fù)載有異常的罪魁禍?zhǔn)拙境鰜?,到時(shí)候從軟件、硬件層面分別尋找解決方案。
2、排查:
從 top 中可以看到 load average 偏高,%wa 偏高,%us 很低:
從上圖我們大致可以推斷 IO 遇到了瓶頸,下面我們可以再用相關(guān)的 IO 診斷工具,具體的驗(yàn)證排查下。
PS:如果你對 top 的用法不了解,請參考我去年寫的一篇博文:
linux 系統(tǒng)監(jiān)控、診斷工具之 top 詳解
常用組合方式有如下幾種:
• 用vmstat、sar、iostat檢測是否是CPU瓶頸 
• 用free、vmstat檢測是否是內(nèi)存瓶頸 
• 用iostat、dmesg 檢測是否是磁盤I/O瓶頸 
• 用netstat檢測是否是網(wǎng)絡(luò)帶寬瓶頸
2.1 vmstat
vmstat命令的含義為顯示虛擬內(nèi)存狀態(tài)(“Viryual Memor Statics”),但是它可以報(bào)告關(guān)于進(jìn)程、內(nèi)存、I/O等系統(tǒng)整體運(yùn)行狀態(tài)。
它的相關(guān)字段說明如下:
- Procs(進(jìn)程)
 - • r: 運(yùn)行隊(duì)列中進(jìn)程數(shù)量,這個(gè)值也可以判斷是否需要增加CPU。(長期大于1)
 - • b: 等待IO的進(jìn)程數(shù)量,也就是處在非中斷睡眠狀態(tài)的進(jìn)程數(shù),展示了正在執(zhí)行和等待CPU資源的任務(wù)個(gè)數(shù)。當(dāng)這個(gè)值超過了CPU數(shù)目,就會(huì)出現(xiàn)CPU瓶頸了
 - Memory(內(nèi)存)
 - • swpd: 使用虛擬內(nèi)存大小,如果swpd的值不為0,但是SI,SO的值長期為0,這種情況不會(huì)影響系統(tǒng)性能。
 - • free: 空閑物理內(nèi)存大小。
 - • buff: 用作緩沖的內(nèi)存大小。
 - • cache: 用作緩存的內(nèi)存大小,如果cache的值大的時(shí)候,說明cache處的文件數(shù)多,如果頻繁訪問到的文件都能被cache處,那么磁盤的讀IO bi會(huì)非常小。
 - Swap
 - • si: 每秒從交換區(qū)寫到內(nèi)存的大小,由磁盤調(diào)入內(nèi)存。
 - • so: 每秒寫入交換區(qū)的內(nèi)存大小,由內(nèi)存調(diào)入磁盤。
 - 注意:內(nèi)存夠用的時(shí)候,這2個(gè)值都是0,如果這2個(gè)值長期大于0時(shí),系統(tǒng)性能會(huì)受到影響,磁盤IO和CPU資源都會(huì)被消耗。有些朋友看到空閑內(nèi)存(free)很少的或接近于0時(shí),就認(rèn)為內(nèi)存不夠用了,不能光看這一點(diǎn),還要結(jié)合si和so,如果free很少,但是si和so也很少(大多時(shí)候是0),那么不用擔(dān)心,系統(tǒng)性能這時(shí)不會(huì)受到影響的。
 - IO(現(xiàn)在的Linux版本塊的大小為1kb)
 - • bi: 每秒讀取的塊數(shù)
 - • bo: 每秒寫入的塊數(shù)
 - 注意:隨機(jī)磁盤讀寫的時(shí)候,這2個(gè)值越大(如超出1024k),能看到CPU在IO等待的值也會(huì)越大。
 - system(系統(tǒng))
 - • in: 每秒中斷數(shù),包括時(shí)鐘中斷。
 - • cs: 每秒上下文切換數(shù)。
 - 注意:上面2個(gè)值越大,會(huì)看到由內(nèi)核消耗的CPU時(shí)間會(huì)越大。
 - CPU(以百分比表示)
 - • us: 用戶進(jìn)程執(zhí)行時(shí)間百分比(user time)
 - us的值比較高時(shí),說明用戶進(jìn)程消耗的CPU時(shí)間多,但是如果長期超50%的使用,那么我們就該考慮優(yōu)化程序算法或者進(jìn)行加速。
 - • sy: 內(nèi)核系統(tǒng)進(jìn)程執(zhí)行時(shí)間百分比(system time)
 - sy的值高時(shí),說明系統(tǒng)內(nèi)核消耗的CPU資源多,這并不是良性表現(xiàn),我們應(yīng)該檢查原因。
 - • wa: IO等待時(shí)間百分比
 - wa的值高時(shí),說明IO等待比較嚴(yán)重,這可能由于磁盤大量作隨機(jī)訪問造成,也有可能磁盤出現(xiàn)瓶頸(塊操作)。
 - • id: 空閑時(shí)間百分比
 
從 vmstat 中可以看到,CPU大部分的時(shí)間浪費(fèi)在等待IO上面,可能是由于大量的磁盤隨機(jī)訪問或者磁盤的帶寬所造成的,bi、bo 也都超過 1024k,應(yīng)該是遇到了IO瓶頸。
2.2 iostat
下面再用更加專業(yè)的磁盤 IO 診斷工具來看下相關(guān)統(tǒng)計(jì)數(shù)據(jù)。
它的相關(guān)字段說明如下:
- rrqm/s: 每秒進(jìn)行 merge 的讀操作數(shù)目。即 delta(rmerge)/s
 - wrqm/s: 每秒進(jìn)行 merge 的寫操作數(shù)目。即 delta(wmerge)/s
 - r/s: 每秒完成的讀 I/O 設(shè)備次數(shù)。即 delta(rio)/s
 - w/s: 每秒完成的寫 I/O 設(shè)備次數(shù)。即 delta(wio)/s
 - rsec/s: 每秒讀扇區(qū)數(shù)。即 delta(rsect)/s
 - wsec/s: 每秒寫扇區(qū)數(shù)。即 delta(wsect)/s
 - rkB/s: 每秒讀K字節(jié)數(shù)。是 rsect/s 的一半,因?yàn)槊可葏^(qū)大小為512字節(jié)。(需要計(jì)算)
 - wkB/s: 每秒寫K字節(jié)數(shù)。是 wsect/s 的一半。(需要計(jì)算)
 - avgrq-sz: 平均每次設(shè)備I/O操作的數(shù)據(jù)大小 (扇區(qū))。delta(rsect+wsect)/delta(rio+wio)
 - avgqu-sz: 平均I/O隊(duì)列長度。即 delta(aveq)/s/1000 (因?yàn)閍veq的單位為毫秒)。
 - await: 平均每次設(shè)備I/O操作的等待時(shí)間 (毫秒)。即 delta(ruse+wuse)/delta(rio+wio)
 - svctm: 平均每次設(shè)備I/O操作的服務(wù)時(shí)間 (毫秒)。即 delta(use)/delta(rio+wio)
 - %util: 一秒中有百分之多少的時(shí)間用于 I/O 操作,或者說一秒中有多少時(shí)間 I/O 隊(duì)列是非空的。即 delta(use)/s/1000 (因?yàn)?/span>use的單位為毫秒)
 
可以看到兩塊硬盤中的 sdb 的利用率已經(jīng) 100%,存在嚴(yán)重的 IO 瓶頸,下一步我們就是要找出哪個(gè)進(jìn)程在往這塊硬盤讀寫數(shù)據(jù)。
2.3 iotop
根據(jù) iotop 的結(jié)果,我們迅速的定位到是 flume 進(jìn)程的問題,造成了大量的 IO wait。
但是在開頭我已經(jīng)說了,集群中的機(jī)器配置一樣,部署的程序也都 rsync 過去的一模一樣,難道是硬盤壞了?
這得找運(yùn)維同學(xué)來查證了,***的結(jié)論是:
Sdb為雙盤raid1,使用raid卡為“LSI Logic / Symbios Logic SAS1068E”,無cache。近400的IOPS壓力已經(jīng)達(dá)到了硬件極限。而其它機(jī)器使用的raid卡是“LSI Logic / Symbios Logic MegaRAID SAS 1078”,有256MB cache,并未達(dá)到硬件瓶頸,解決辦法是更換能提供更大IOPS的機(jī)器。
不過前面也說了,我們從軟硬件兩方面著手的目的就是看能否分別尋求代價(jià)最小的解決方案:
 
知道硬件的原因了,我們可以嘗試把讀寫操作移到另一塊盤,然后再看看效果:
3、***的話:另辟蹊徑
其實(shí),除了用上述專業(yè)的工具定位這個(gè)問題外,我們可以直接利用進(jìn)程狀態(tài)來找到相關(guān)的進(jìn)程。
我們知道進(jìn)程有如下幾種狀態(tài):
- 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.
 
其中狀態(tài)為 D 的一般就是由于 wait IO 而造成所謂的”非中斷睡眠“,我們可以從這點(diǎn)入手然后一步步的定位問題:
- for x in `seq 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 [kdmflush]
 - D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
 - ----
 - # 或者:
 - while true; do date; ps auxf | awk '{if($8=="D") print $0;}'; sleep 1; done
 - Tue Aug 23 20:03:54 CLT 2011
 - root 302 0.0 0.0 0 0 ? D May22 2:58 \_ [kdmflush]
 - root 321 0.0 0.0 0 0 ? D May22 4:11 \_ [jbd2/dm-0-8]
 - Tue Aug 23 20:03:55 CLT 2011
 - Tue Aug 23 20:03:56 CLT 2011
 - cat /proc/16528/io
 - rchar: 48752567
 - wchar: 549961789
 - syscr: 5967
 - syscw: 67138
 - read_bytes: 49020928
 - write_bytes: 549961728
 - cancelled_write_bytes: 0
 - 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</strong>
 - df /tmp
 - Filesystem 1K-blocks Used Available Use% Mounted on
 - /dev/mapper/workstation-root 7667140 2628608 4653920 37% /
 - fuser -vm /tmp
 - USER PID ACCESS COMMAND
 - /tmp: db2fenc1 1067 ....m db2fmp
 - db2fenc1 1071 ....m db2fmp
 - db2fenc1 2560 ....m db2fmp
 - db2fenc1 5221 ....m db2fmp
 
4、Refer:
[1] Troubleshooting High I/O Wait in Linux
——A walkthrough on how to find processes that are causing high I/O Wait on Linux Systems
http://bencane.com/2012/08/06/troubleshooting-high-io-wait-in-linux/
[2] 理解Linux系統(tǒng)負(fù)荷
http://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html
 
[3] 24 iostat, vmstat and mpstat Examples for Linux Performance Monitoring
http://www.thegeekstuff.com/2011/07/iostat-vmstat-mpstat-examples/
 
[4] vmstat vmstat命令
[5] Linux vmstat命令實(shí)戰(zhàn)詳解
http://www.cnblogs.com/ggjucheng/archive/2012/01/05/2312625.html
[6] 影響Linux服務(wù)器性能的因素
http://www.rocklv.net/2004/news/article_284.html
 
[7] linux磁盤IO查看iostat,vmstat
http://blog.csdn.net/qiudakun/article/details/4699587
 
[8] What Process is using all of my disk IO
http://stackoverflow.com/questions/488826/what-process-is-using-all-of-my-disk-io
[9] Linux Wait IO Problem
http://www.chileoffshore.com/en/interesting-articles/126-linux-wait-io-problem
 
[10] Tracking Down High IO Wait in Linux




















 
 
 



 
 
 
 