linux效能 --》load average解讀

朱清震發表於2017-07-01

什麼是load

load代表cup的執行佇列,每個CPU都會維持一個執行佇列,理想情況下,排程器會不斷讓佇列中的程式執行。程式不是處在sleep狀態就是runable狀態。一種情況是CPU過載,就會出現排程器跟不上系統的要求,導致可執行的程式會填滿佇列。佇列愈大,程式執行時間就愈長;還有一種情況是程式再等待其他資源如磁碟io、網路io等,這時候就會出現執行佇列很大,但是cpu負載卻不高。

在linux中load average這一指標代表了cup的load;

網上很多講解load average的文章都是在片面的講cpu密集型應用的load狀況,這會給大家帶來誤導;load average指標需要結合系統cpu的核數、cpu佔有率,io等資源的情況來分析系統的負載,單看load average是沒有意義的;

如何檢視load

a. 通過top命令

top -  11:37:48 up 7 days, 17:42,  9 users,  load average: 0.00, 0.00, 0.00

top命令的第一行,最後一個指標load average的三個值分別代表了當前cpu任務佇列 1分鐘、5分鐘、15分鐘的平均值;

b. uptime命令

[root@report bin] # uptime
11:39:08 up 7 days, 17:43, 9 users, load average: 0.00, 0.00, 0.00

c. w 命令

[root@report bin ] #  w
 11:41:08 up 7 days, 17:45,  9 users,  load average: 0.00, 0.00, 0.00

如何分析

根據 CPU 數量去判斷,系統負載情況;

平均每個cpu的負載 = load /cpu數量

這個值過高代表需要執行的佇列累積過多了。
但佇列中的任務實際可能是耗 CPU的,也可能是耗 I/O 乃至其它因素的。

這個值判斷有兩種情況:

  1. 如果這個值持續大於等於1,並且cup佔用率非常高,說明任務佇列裡的任務大部分或全部都是cpu計算型的任務,這時候cpu已經滿載,如果這個值大於3說明cpu負載已經很高;

  2. 如果這個值很大,但是cpu佔用率卻不高,說明有很多執行緒處於其它資源的等待狀態,這個時候通過top -H 命令,展示執行緒,然後按shift + o ,進入排序頁面,再按 w,對程式狀態排序;

觀察執行緒的狀態,執行緒有以下5中狀態:
D 表示不中斷休眠
R 表示正在執行
S 表示休眠
T 表示被跟蹤或被停止
Z 表示出於僵死狀態

如果狀態為D的執行緒很多,說明這些執行緒在等待資源排程,如磁碟io、網路io或其它資源;
所以這個時候要檢查其它資源是否存在瓶頸或故障;

總結

所以load過高的原因有兩個,處於Running狀態和D狀態的執行緒太多導致的;

如果處於running狀態的執行緒太多,會導致cpu佔用率很高,如果處於D狀態的執行緒太多,那麼就要檢視是否系統其他資源到了瓶頸

關於程式狀態D

執行緒等待資源而去睡眠,就會進入D狀態( 即Disk sleep,深度睡眠 ),進入D狀態的執行緒是不能夠被打斷的,他們會一直睡眠直到等待的資源被釋放時主動去喚醒他們。

Linux 程式有兩種睡眠狀態:

interruptible sleep,處在這種睡眠狀態的程式是可以通過給它發訊號來喚醒的;
uninterruptible sleep,處在這種狀態的程式不接受外來的任何訊號,因為此時這個程式正執行在核心態,CRTL+C是給程式發signal的方式通知程式,而程式只有在從核心態返回使用者態的時候才會去檢查有沒有訊號,所以如果它處在核心態的話顯然是無法被殺死的,這也是為什麼用 kill 殺掉這些處於 D 狀態的程式,無論是 kill, kill -9 還是 kill -15。

D 狀態就是 uninterruptible sleep
程式為什麼會被置於 uninterruptible sleep 狀態呢?處於 uninterruptible sleep 狀態的程式通常是在等待 IO,比如磁碟 IO,網路 IO,其他外設 IO,如果程式正在等待的 IO 在較長的時間內都沒有響應,也就意味著很有可能有 IO 出了問題,可能是外設本身出了故障,比如掛載的遠端檔案系統已經不可訪問了;正是因為得不到 IO 的響應,程式才進入了 uninterruptible sleep 狀態,所以要想使程式從 uninterruptible sleep 狀態恢復,就得使程式等待的 IO 恢復,比如如果是因為從遠端掛載的 NFS 卷不可訪問導致程式進入 uninterruptible sleep 狀態的,那麼可以通過恢復該 NFS 卷的連線來使程式的 IO 請求得到滿足;

進入該狀態的程式,會一直等待,不接受任何訊號,當然也就無法被殺死(kill/fuser -k)。因為程式一直在執行佇列(running queue)中,所以還會導致主機的Load上升(雖然主機並不繁忙)。如果由於這個原因被卡住的程式很多的話,主機的Load可能會看起來非常高。

相關文章