Linux命令拾遺之理解系統(tǒng)負載(整理分享)

本篇文章給大家?guī)砹?a >linux中負載的概念與問題診斷方法相關(guān)知識,其中包括了負載是什么以及線程狀態(tài)等,希望對大家有幫助。

Linux命令拾遺之理解系統(tǒng)負載(整理分享)

一般在類unix系統(tǒng)上,都會有系統(tǒng)負載(load average)這個指標,用來形容系統(tǒng)的繁忙程度,值越大則代表系統(tǒng)越繁忙。??

查看負載?

$?uptime 19:59:57?up?29?days,??7:08,??1?user,??load?average:?0.57,?0.26,?0.18

我們關(guān)注load average后的3個值,分別代表1分鐘、5分鐘、15分鐘的系統(tǒng)平均負載,如果1分鐘值>5分鐘值>15分鐘值,則代表近15分鐘內(nèi)系統(tǒng)壓力越來越大,反之亦然。?

同樣,在top命令的第一行,也能看到系統(tǒng)負載,它的含義和uptime是一樣的。?

負載是什么?

一般來說,系統(tǒng)線程基本都在這3個狀態(tài)上:運行中,可運行,阻塞等待,其中,運行中的線程正在CPU上跑,可運行的線程等待CPU調(diào)度,而阻塞的線程等待鎖釋放或io完成。?

在傳統(tǒng)unix系統(tǒng)上(如BSD),系統(tǒng)負載由正在運行的線程以及可運行的線程這2個部分組成。?

它能很好的說明CPU的飽和情況,比如4核的CPU,如果負載一直高于4,那說明CPU資源飽和了。?

linux擴大了負載的定義,如下:?

Linux負載由正在運行的線程和可運行的線程,以及D狀態(tài)的線程(一般是等待io完成)這3個部分組成。?

因為Linux認為,雖然D狀態(tài)的線程并不消耗CPU資源,但是它會消耗磁盤、網(wǎng)卡等硬件資源以及鎖這樣的軟件資源,因此它也應(yīng)該被用來計算系統(tǒng)負載,想來也合理,畢竟系統(tǒng)負載是用來描述整個系統(tǒng)的繁忙程度的,而不僅僅是CPU的。?

線程狀態(tài)D

在Linux里面,線程有如下常見狀態(tài):?

  • R: 正在運行或可運行狀態(tài)??

  • S: 睡眠狀態(tài),被阻塞等待喚醒??

  • D: 不可中斷睡眠狀態(tài),一般是等待io完成? ?

這里面的R與D狀態(tài)的線程會影響系統(tǒng)負載,因此,當系統(tǒng)負載較高時,可以通過如下命令了解是哪些線程導致的:?

ps?-eLo?pid,tid,stat,comm?|?grep?-E?"?R|D"

小實驗:將系統(tǒng)負載升到100

# 使用vfork函數(shù)創(chuàng)建一個子進程,子進程如果不調(diào)用exec系統(tǒng)調(diào)用,它的狀態(tài)會一直是D。

$?cat?uninterruptible.c? int?main()?{ ????vfork(); ????sleep(600); ????return?0; } #?編譯成可執(zhí)行程序 $?gcc?-o?uninterruptible?uninterruptible.c #?運行100個程序 $?for?i?in?{1..100};?do?./uninterruptible?&;?done

等待1分鐘,就會發(fā)現(xiàn)系統(tǒng)負載升到了快100,如下:

$?uptime 20:24:42?up?29?days,??7:32,??1?user,??load?average:?99.94,?74.82,?35.87 #?可以看到很多D狀態(tài)的進程 $?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命令可以看到線程狀態(tài),還有一個wchan字段,它顯示的是線程當前被阻塞在什么內(nèi)核函數(shù)上,這能看出一些蛛絲馬跡。?

另外,通過/proc/sysrq-trigger可以看到D線程阻塞時的代碼路徑,如下:?

#?寫入一個w即可,需要root權(quán)限執(zhí)行 $?echo?w?>?/proc/sysrq-trigger #?然后內(nèi)核會把D狀態(tài)線程調(diào)用棧輸出到內(nèi)核日志,這可以通過dmesg查看 $?dmesg

Linux命令拾遺之理解系統(tǒng)負載(整理分享)

這里就能很清楚的看到,是由于vfork系統(tǒng)調(diào)用引起的負載上升。?

之前介紹過bcc工具集里的offcputime工具,它可以用來繪制offcpu火焰圖,同樣的,診斷高負載問題時,也可以用這個工具,傳一個參數(shù),讓其只關(guān)注D狀態(tài)線程的offcpu行為即可,如下:?

#?ubuntu安裝bcc工具集 $?sudo?apt?install?bpfcc-tools #?使用root身份進入bash $?sudo?bash #?--state?2用于指定抓取TASK_UNINTERRUPTIBLE即D狀態(tài)線程的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命令拾遺之理解系統(tǒng)負載(整理分享)

相關(guān)推薦:《Linux視頻教程

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊15 分享