
CPU使?率低負載?的原因
原因總結
產?的原因?句話總結就是:等待磁盤I/O完成的進程過多,導致進程隊列長度過?,但是cpu運?的進程卻很少,這樣就體現到負載過?了,cpu使?率低。
下?內容是具體的原理分析:
在分析負載為什么?之前先介紹下什么是負載、多任務操作系統、進程調度等相關概念。
什么是負載
什么是負載:負載就是cpu在?段時間內正在處理以及等待cpu處理的進程數之和的統計信息,也就是cpu使?隊列的長度統計信息,這個數字越?越好(如果超過CPU核?*0.7就是不正常)
負載分為兩?部分:CPU負載、IO負載
例如,假設有?個進??規模科學計算的程序,雖然該程序不會頻繁地從磁盤輸?輸出,但是處理完成需要相當長的時間。因為該程序主要被?來做計算、邏輯判斷等處理,所以程序的處理速度主要依賴于cpu的計算速度。此類cpu負載的程序稱為“計算密集型程序”。
還有?類程序,主要從磁盤保存的?量數據中搜索找出任意?件。這個搜索程序的處理速度并不依賴于cpu,?是依賴于磁盤的讀取速度,也就是輸?輸出(input/output,I/O).磁盤越快,檢索花費的時間就越短。此類I/O負載的程序,稱為“I/O密集型程序”。
什么是多任務操作系統
Linux操作系統能夠同時處理?個不同名稱的任務。但是同時運?多個任務的過程中,cpu和磁盤這些有限的硬件資源就需要被這些任務程序共享。即便很短的時間間隔內,需要?邊在這些任務之間進?切換到?邊進?處理,這就是多任務。
運?中的任務較少的情況下,系統并不是等待此類切換動作的發?。但是當任務增加時,例如任務A正在CPU上執?計算,接下來如果任務B和C也想進?計算,那么就需要等待CPU空閑。也就是說,即便是運?處理某任務,也要等到輪到他時才能運?,此類等待狀態就表現為程序運?延遲。
uptime輸出中包含“load average”的數字
[root@localhost ~]# uptime
11:16:38 up 2:06, 4 urs, load average: 0.00, 0.02, 0.05
Load average從左邊起依次是過去1分鐘、5分鐘、15分鐘內,單位時間的等待任務數,也就是表?平均有多少任務正處于等待狀態。在load average較?的情況下,這就說明等待運?的任務較多,因此輪到該任務運?的等待時間就會出現較?的延遲,即反映了此時負載較?。
進程調度
什么是進程調度:
進程調度也被?些?稱為cpu上下?切換意思是:CPU切換到另?個進程需要保存當前進程的狀態并恢復另?個進程的狀態:當前運?任務轉為就緒(或者掛起、中斷)狀態,另?個被選定的就緒任務成為當前任務。進程調度包括保存當前任務的運?環境,恢復將要運?任務的運?環境。
在linux內核中,每?個進程都存在?個名為“進程描述符”的管理表。該進程描述符會調整為按照優先級降序排序,已按合理的順序運?進程(任務)。這個調整即為進程調度器的?作。
調度器劃分并管理進程的狀態,如:
等待分配cpu資源的狀態。
等待磁盤輸?輸出完畢的狀態。
下?在說?下進程的狀態區別:
狀態說明
運?態(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)和不可中斷狀態(interruptible)才會被加?到負載等待進程中,也就是下?這兩種情況的進程才會表現為負載的值。
即便需要?即使?CPU,也還需等待其他進程?完CPU
即便需要繼續處理,也必須等待磁盤輸?輸出完成才能進?
下?描述?種直觀感受的場景說明為什么只有運?態(running)和可中斷狀態(interruptible)才會被加?負載。
如:在很占?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 rver故障?如我們的系統掛載了外接硬盤如NFS共享存儲,經常會有?量的讀寫請求去訪問NFS存儲的?件,如果這個時候NFS Server故障,那么就會導致進程讀寫請求?直獲取不到資源,從?進程?直是不可中斷狀態,造成負載很?。
--------------------
常見的處理辦法
?站相關進程導致負載?處理辦法:
1、直接把?站php或http或tomcat等?站服務重啟,很多時候負載就降下來了
2、也可能是?站代碼漏洞導致的,需要反饋開發?起查找原因和處理
3、把重復的tomcat kill全部掉重新啟動
mysql進程導致的負載?處理辦法:
1、常見的就是mysql慢查詢導致,可以在mysql慢查詢?志找到相關sql語句,這需要對sql進?優化
2、還可以進?mysql,?show full processlist\G;查看那個mysql進程執?時間?較久的慢查詢。如果是內部后臺使?的語句,可以先kill掉,優化后再執?。
3、mysql讀寫太頻繁,如果是讀寫頻繁可以在%wa等待輸?輸出看的出來占?cpu百分?很?。也可以通過命令iostat查看系統讀寫情況。
還有可能是?絡原因,系統硬件原因等