關(guān)于CPU使用率相關(guān)重要指標(biāo),我們經(jīng)常在使用top、dstat、vmstat等工具看到,這里解讀一下:
- user(通常縮寫為us),代表用戶態(tài)CPU時(shí)間。
- nice(通常縮寫為ni),代表低優(yōu)先級(jí)用戶態(tài)CPU時(shí)間,nice可取值范圍是-20到19,數(shù)值越大,優(yōu)先級(jí)反而越低,默認(rèn)值是0。
- system(通常縮寫為sys),代表內(nèi)核態(tài)CPU時(shí)間。
- idle(通常縮寫為id),代表空閑時(shí)間。注意,它不包括等待I/O的時(shí)間(iowAIt)。
- iowait(通常縮寫為wa),代表等待 I/O的CPU時(shí)間。
- irq(通常縮寫為hi),代表處理硬中斷的CPU時(shí)間。
- softirq(通常縮寫為si),代表處理軟中斷的CPU時(shí)間。
- steal(通常縮寫為st),代表當(dāng)系統(tǒng)運(yùn)行在虛擬機(jī)中的時(shí)候,虛擬機(jī)占用的CPU時(shí)間。
- guest(通常縮寫為guest),代表通過虛擬化運(yùn)行其他操作系統(tǒng)的時(shí)間,也就是運(yùn)行虛擬機(jī)的CPU時(shí)間。
- guest_nice(通常縮寫為gnice),代表以低優(yōu)先級(jí)運(yùn)行虛擬機(jī)的時(shí)間。
CPU的iowait突然升高,我該怎么處理?
分析過程
從上面的介紹可以看出,iowait升高,第一反應(yīng)會(huì)想到查看系統(tǒng)的 I/O情況,I/O又分為磁盤I/O和網(wǎng)絡(luò)I/O,這里先分析磁盤I/O。
1、運(yùn)行 dstat 命令,觀察 CPU 和 I/O 的使用情況
- 結(jié)果分析。
- 在iowait升高(wai)時(shí),磁盤的讀請(qǐng)求(read)都很高,最高時(shí)1271M。
- 充分說明iowait的升高是磁盤I/O導(dǎo)致的,確切的說,是大量讀磁盤導(dǎo)致的。
2、通過pidstat查詢進(jìn)程的I/O情況
# -d:統(tǒng)計(jì)進(jìn)程的磁盤使用情況 1: 采集周期1s 10: 采集10次
pidstat -d 1 10
- 1.
- 2.
- 結(jié)果分析。
- 大量讀磁盤的進(jìn)程名稱是App,而且app進(jìn)程的pid在不停變化(短時(shí)進(jìn)程?)
3、使用ps命令查看下app進(jìn)程
- 結(jié)果分析。
- 進(jìn)程的狀態(tài)是Z+,命令行參數(shù)<defunct>,進(jìn)程變成僵尸進(jìn)程了。
- 僵尸進(jìn)程的產(chǎn)生和處理方法,這里暫不展開,有想了解的可以評(píng)論留言或者自行學(xué)習(xí)。
- app的是誰創(chuàng)建的,是下一步分析的重點(diǎn)。
4、查詢app進(jìn)程的父進(jìn)程
- 結(jié)果分析。
- pid為51780的父進(jìn)程id是51688,進(jìn)程名稱也是app。
5、使用perf命令采集性能事件分析app函數(shù)調(diào)用
# 錄制全局性能事件,如果只想錄制某個(gè)進(jìn)程的,可以使用-p指定
# perf record -ag -p {pid} -- sleep 10 #采集指定pid所有cpu的性能事件,周期是10s
perf record -g
# 分析報(bào)告
perf report
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 分析結(jié)果。
- app進(jìn)程正在對(duì)磁盤進(jìn)行直接讀,也就是繞過了系統(tǒng)緩存,每個(gè)讀請(qǐng)求都會(huì)從磁盤直接讀。
思路總結(jié)
- 使用dstat命令查看系統(tǒng)I/O情況(dstat可以同時(shí)觀察cpu和磁盤的情況)。
- 使用pidstat命令可以定位到進(jìn)程維度的磁盤讀寫情況,找出可疑進(jìn)程。
- 使用ps、top等命令可以觀測(cè)到進(jìn)程的狀態(tài)(D、R、S、Z、T等)。
- 使用pstree命令我們找出了app進(jìn)程的父進(jìn)程(子進(jìn)程的pid一直在變)。
- 使用perf命令就可以對(duì)進(jìn)程的函數(shù)調(diào)用關(guān)系分析了。
- 沒啥需要使用的啦。哈哈,點(diǎn)贊+收藏。
知識(shí)補(bǔ)充
進(jìn)程狀態(tài)
- R 是Running或Runnable 的縮寫,表示進(jìn)程在CPU的就緒隊(duì)列中,正在運(yùn)行或者正在等待運(yùn)行。
- D 是Disk Sleep的縮寫,也就是不可中斷狀態(tài)睡眠(Uninterruptible Sleep),一般表示進(jìn)程正在跟硬件交互,并且交互過程不允許被其他進(jìn)程或中斷打斷。
- Z 是Zombie的縮寫,進(jìn)程實(shí)際上已經(jīng)結(jié)束了,但是父進(jìn)程還沒有回收它的資源(比如進(jìn)程的描述符、PID 等)。
- S 是Interruptible Sleep的縮寫,也就是可中斷狀態(tài)睡眠,表示進(jìn)程因?yàn)榈却硞€(gè)事件而被系統(tǒng)掛起。當(dāng)進(jìn)程等待的事件發(fā)生時(shí),它會(huì)被喚醒并進(jìn)入R狀態(tài)。
- I 是Idle的縮寫,也就是空閑狀態(tài),用在不可中斷睡眠的內(nèi)核線程上。
- T 或者 t,也就是Stopped或Traced的縮寫,表示進(jìn)程處于暫停或者跟蹤狀態(tài)。
僵尸進(jìn)程
- 一旦父進(jìn)程沒有處理子進(jìn)程的終止,還一直保持運(yùn)行狀態(tài),那么子進(jìn)程就會(huì)一直處于僵尸狀態(tài)。
- 大量的僵尸進(jìn)程會(huì)用盡PID進(jìn)程號(hào),導(dǎo)致新進(jìn)程不能創(chuàng)建。
- 僵尸進(jìn)程在父進(jìn)程回收它的資源后就會(huì)消亡,或者在父進(jìn)程退出后,由init進(jìn)程回收后也會(huì)消亡。