共計 2265 個字符,預計需要花費 6 分鐘才能閱讀完成。
這篇文章主要介紹“Linux 中怎么理解系統負載”,在日常操作中,相信很多人在 Linux 中怎么理解系統負載問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Linux 中怎么理解系統負載”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!
一般在類 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 中怎么理解系統負載”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!