一般在類unix系統上,都會有系統負載(load average)這個指標,用來形容系統的繁忙程度,值越大則代表系統越繁忙。
檢視負載
$ uptime 19:59:57 up 29 days, 7:08, 1 user, load average: 0.57, 0.26, 0.18
我們關注load average後的3個值,分別代表1分鐘、5分鐘、15分鐘的系統平均負載,如果1分鐘值>5分鐘值>15分鐘值,則代表近15分鐘內系統壓力越來越大,反之亦然。
同樣,在top命令的第一行,也能看到系統負載,它的含義和uptime是一樣的。
負載是什麼
一般來說,系統執行緒基本都在這3個狀態上:執行中,可執行,阻塞等待,其中,執行中的執行緒正在CPU上跑,可執行的執行緒等待CPU排程,而阻塞的執行緒等待鎖釋放或io完成。
在傳統unix系統上(如BSD),系統負載由正在執行的執行緒以及可執行的執行緒這2個部分組成。
它能很好的說明CPU的飽和情況,比如4核的CPU,如果負載一直高於4,那說明CPU資源飽和了。
而Linux擴大了負載的定義,如下:
Linux負載由正在執行的執行緒和可執行的執行緒,以及D狀態的執行緒(一般是等待io完成)這3個部分組成。
因為Linux認為,雖然D狀態的執行緒並不消耗CPU資源,但是它會消耗磁碟、網路卡等硬體資源以及鎖這樣的軟體資源,因此它也應該被用來計算系統負載,想來也合理,畢竟系統負載是用來描述整個系統的繁忙程度的,而不僅僅是CPU的。
執行緒狀態D
在Linux裡面,執行緒有如下常見狀態:
R: 正在執行或可執行狀態
S: 睡眠狀態,被阻塞等待喚醒
D: 不可中斷睡眠狀態,一般是等待io完成
這裡面的R與D狀態的執行緒會影響系統負載,因此,當系統負載較高時,可以通過如下命令瞭解是哪些執行緒導致的:
ps -eLo pid,tid,stat,comm | grep -E " R|D"
小實驗:將系統負載升到100
# 使用vfork函數建立一個子程序,子程序如果不呼叫exec系統呼叫,它的狀態會一直是D。
$ cat uninterruptible.c int main() { vfork(); sleep(600); return 0; } # 編譯成可執行程式 $ gcc -o uninterruptible uninterruptible.c # 執行100個程式 $ for i in {1..100}; do ./uninterruptible &; done
等待1分鐘,就會發現系統負載升到了快100,如下:
$ uptime 20:24:42 up 29 days, 7:32, 1 user, load average: 99.94, 74.82, 35.87 # 可以看到很多D狀態的程序 $ ps -eLo pid,tid,stat,pcpu,wchan:32,comm | grep " D" 3774195 3774195 D 0.0 do_fork uninterruptible 3774196 3774196 D 0.0 do_fork uninterruptible 3774197 3774197 D 0.0 do_fork uninterruptible 3774198 3774198 D 0.0 do_fork uninterruptible
如上,通過ps命令可以看到執行緒狀態,還有一個wchan欄位,它顯示的是執行緒當前被阻塞在什麼核心函數上,這能看出一些蛛絲馬跡。
另外,通過/proc/sysrq-trigger可以看到D執行緒阻塞時的程式碼路徑,如下:
# 寫入一個w即可,需要root許可權執行 $ echo w > /proc/sysrq-trigger # 然後核心會把D狀態執行緒呼叫棧輸出到核心紀錄檔,這可以通過dmesg檢視 $ dmesg
這裡就能很清楚的看到,是由於vfork系統呼叫引起的負載上升。
之前介紹過bcc工具集裡的offcputime工具,它可以用來繪製offcpu火焰圖,同樣的,診斷高負載問題時,也可以用這個工具,傳一個引數,讓其只關注D狀態執行緒的offcpu行為即可,如下:
# ubuntu安裝bcc工具集 $ sudo apt install bpfcc-tools # 使用root身份進入bash $ sudo bash # --state 2用於指定抓取TASK_UNINTERRUPTIBLE即D狀態執行緒的offcpu棧 $ offcputime-bpfcc -K --state 2 -f 60 > d_state_offcpu_stack.out # 繪製為offcpu火焰圖 $ awk '{ print $1, $2 / 1000 }' d_state_offcpu_stack.out | ./FlameGraph/flamegraph.pl --color=io --countname=ms > d_state_offcpu.svg
相關推薦:《Linux視訊教學》
以上就是Linux命令拾遺之理解系統負載(整理分享)的詳細內容,更多請關注TW511.COM其它相關文章!