cpu使用率低負載高,原因分析

原因總結

產生的原因一句話總結就是:等待磁盤I/O完成的進程過多,導致進程隊列長度過大,但是cpu運行的進程卻很少,這樣就體現到負載過大了,cpu使用率低。
下面內容是具體的原理分析:在分析負載為什么高之前先介紹下什么是負載、多任務操作系統、進程調度等相關概念。

什么是負載

什么是負載:負載就是cpu在一段時間內正在處理以及等待cpu處理的進程數之和的統計信息,也就是cpu使用隊列的長度統計信息,這個數字越小越好(如果超過CPU核心*0.7就是不正常)
負載分為兩大部分:CPU負載、IO負載
例如,假設有一個進行大規??茖W計算的程序,雖然該程序不會頻繁地從磁盤輸入輸出,但是處理完成需要相當長的時間。因為該程序主要被用來做計算、邏輯判斷等處理,所以程序的處理速度主要依賴于cpu的計算速度。此類cpu負載的程序稱為“計算密集型程序”。
還有一類程序,主要從磁盤保存的大量數據中搜索找出任意文件。這個搜索程序的處理速度并不依賴于cpu,而是依賴于磁盤的讀取速度,也就是輸入輸出(input/output,I/O).磁盤越快,檢索花費的時間就越短。此類I/O負載的程序,稱為“I/O密集型程序”。

什么是多任務操作系統

Linux操作系統能夠同時處理幾個不同名稱的任務。但是同時運行多個任務的過程中,cpu和磁盤這些有限的硬件資源就需要被這些任務程序共享。即便很短的時間間隔內,需要一邊在這些任務之間進行切換到一邊進行處理,這就是多任務。
運行中的任務較少的情況下,系統并不是等待此類切換動作的發生。但是當任務增加時,例如任務A正在CPU上執行計算,接下來如果任務B和C也想進行計算,那么就需要等待CPU空閑。也就是說,即便是運行處理某任務,也要等到輪到他時才能運行,此類等待狀態就表現為程序運行延遲。

11:48:16 up 34 days, 34 min, 1 user, load average: 9.25, 11.39, 11.11
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 119.40.36.230 10:05 0.00s 0.00s 0.00s w

Load average從左邊起依次是過去1分鐘、5分鐘、15分鐘內,單位時間的等待任務數,也就是表示平均有多少任務正處于等待狀態。在load average較高的情況下,這就說明等待運行的任務較多,因此輪到該任務運行的等待時間就會出現較大的延遲,即反映了此時負載較高。

進程調度

什么是進程調度:
進程調度也被一些人稱為cpu上下文切換意思是:CPU切換到另一個進程需要保存當前進程的狀態并恢復另一個進程的狀態:當前運行任務轉為就緒(或者掛起、中斷)狀態,另一個被選定的就緒任務成為當前任務。進程調度包括保存當前任務的運行環境,恢復將要運行任務的運行環境。
在linux內核中,每一個進程都存在一個名為“進程描述符”的管理表。該進程描述符會調整為按照優先級降序排序,已按合理的順序運行進程(任務)。這個調整即為進程調度器的工作。
調度器劃分并管理進程的狀態,如:
等待分配cpu資源的狀態。
等待磁盤輸入輸出完畢的狀態。

下面在說一下進程的狀態區別:
進程5大狀態說明

運行態(running)

只要cpu空閑,任何時候都可以運行

可中斷睡眠(interruptible)

為恢復時間無法預測的長時間等待狀態。如,來自于鍵盤設備的輸入。

不可中斷睡眠:(uninterruptible)

主要為短時間時的等待狀態。例如磁盤輸入輸出等待。被IO阻塞的進程

就緒態(runnable)

響應暫停信號而運行的中斷狀態。

僵死態(zombie)

進程都是由父進程創建,并銷毀;在父進程沒有銷毀其子進程,被銷毀的時候,其子進程由于沒有父進程被銷毀,就會轉變為僵死態。

下面舉例來說明進程狀態轉變:
這里有三個進程A、B、C同時運行。首先,每個進程在生成后都是可運行狀態,也就是running狀態的開始,而不是現在運行狀態,由于在linux內核中無法區別正在運行的狀態和可運行的等待狀態,下面將可運行狀態和正在運行狀態都稱為running狀態。
進程A:running
進程B:running
進程C:running

running的三個進程立即成為調度對象。此時,假設調度器給進程A分配了CPU的運行權限。
進程A:running (正在運行)
進程B:running
進程C:running

進程A分配了CPU,所以進程A開始處理。進程B和C則在此等待進程A遷出CPU。假設進程A進行若干計算之后,需要從磁盤讀取數據。那么在A發出讀取磁盤數據的請求之后,到請求數據到達之前,將不進行任何工作。此狀態稱為“因等待I/O操作結束而被阻塞”。在I/O完成處理前,進程A就一直處于等待中,就會轉為不可中斷睡眠狀態(uninterruptible),并不使用CPU。于是調度器查看進程B和進程C的優先級計算結果,將CPU運行權限交給優先級較高的一方。這里假設進程B的優先級高于進程C。
進程A:uninterruptible (等待磁盤輸入輸出/不可中斷狀態)
進程B:running (正在運行)
進程C:running

進程B剛開始運行,就需要等待用戶的鍵盤輸入。于是B進入等待用戶鍵盤輸入狀態,同樣被阻塞。結果就變成了進程A和進程B都是等待輸出,運行進程C。這時進程A和進程B都是等待狀態,但是等待磁盤輸入輸出和等待鍵盤輸入為不同的狀態。等待鍵盤輸入是無限期的事件等待,而讀取磁盤則是必須短時間內完成的事件等待,這是兩種不同的等待狀態。各進程狀態如下所示:
進程A:uninterruptible (等待磁盤輸入輸出/不可中斷狀態)
進程B:interruptible (等待鍵盤輸入輸出/可中斷狀態)
進程C:running (正在運行)

這次假設進程C在運行的過程中,進程A請求的數據從磁盤到達了緩沖裝置。緊接著硬盤對內核發起中斷信號,內核知道磁盤讀取完成,將進程A恢復為可運行狀態。
進程A:running (正在運行)
進程B:interruptible (等待鍵盤輸入輸出/可中斷狀態)
進程C:running (正在運行)

此后進程C也會變為某種等待狀態。如CPU的占用時間超出了上限、任務結束、進入I/O等待。一旦滿足這些條件,調度器就可以完成從進程C到進程A的進程狀態切換。

負載的意義:

負載表示的是“等待進程的平均數”。在上面的進程狀態變換過程中,除了running狀態,其他都是等待狀態,那么其他狀態都會加入到負載等待進程中嗎?
事實證明,只有進程處于運行態(running)和不可中斷狀態(uninterruptible)才會被加入到負載等待進程中,也就是下面這兩種情況的進程才會表現為負載的值。
即便需要立即使用CPU,也還需等待其他進程用完CPU
即便需要繼續處理,也必須等待磁盤輸入輸出完成才能進行

下面描述一種直觀感受的場景說明為什么只有運行態(running)和不可中斷狀態(uninterruptible)才會被加入負載。

如:在很占用CPU資源的處理中,例如在進行動畫編碼的過程中,雖然想進行其他相同類型的處理,結果系統反映卻變得很慢,還有從磁盤讀取大量數據時,系統的反映也同樣會變的很慢。但是另一方面,無論有多少等待鍵盤輸入輸出操作的進程,也不會讓系統響應變慢。
什么場景會造成CPU低而負載確很高呢?
通過上面的具體分析負載的意義就很明顯了,負載總結為一句話就是:需要運行處理但又必須等待隊列前的進程處理完成的進程個數。具體來說,也就是如下兩種情況:
等待被授權予CPU運行權限的進程
等待磁盤I/O完成的進程

cpu低而負載高也就是說等待磁盤I/O完成的進程過多,就會導致隊列長度過大,這樣就體現到負載過大了,但實際是此時cpu被分配去執行別的任務或空閑,具體場景有如下幾種。

場景一:磁盤讀寫請求過多就會導致大量I/O等待

上面說過,cpu的工作效率要高于磁盤,而進程在cpu上面運行需要訪問磁盤文件,這個時候cpu會向內核發起調用文件的請求,讓內核去磁盤取文件,這個時候會切換到其他進程或者空閑,這個任務就會轉換為不可中斷睡眠狀態。當這種讀寫請求過多就會導致不可中斷睡眠狀態的進程過多,從而導致負載高,cpu低的情況。

場景二:MySQL中存在沒有索引的語句或存在死鎖等情況

我們都知道MySQL的數據是存儲在硬盤中,如果需要進行sql查詢,需要先把數據從磁盤加載到內存中。當在數據特別大的時候,如果執行的sql語句沒有索引,就會造成掃描表的行數過大導致I/O阻塞,或者是語句中存在死鎖,也會造成I/O阻塞,從而導致不可中斷睡眠進程過多,導致負載過大。
具體解決方法可以在MySQL中運行show full processlist命令查看線程等待情況,把其中的語句拿出來進行優化。

場景三:外接硬盤故障,常見有掛了NFS,但是NFS server故障

比如我們的系統掛載了外接硬盤如NFS共享存儲,經常會有大量的讀寫請求去訪問NFS存儲的文件,如果這個時候NFS Server故障,那么就會導致進程讀寫請求一直獲取不到資源,從而進程一直是不可中斷狀態,造成負載很高。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容