CPU load過高問題排查

load average的概念

top命令中load average顯示的是最近1分鐘、5分鐘和15分鐘的系統平均負載。

系統平均負載被定義爲在特定時間間隔內運行隊列中(在CPU上運行或者等待運行多少進程)的平均進程數。如果一個進程滿足以下條件則其就會位於運行隊列中:

  • 它沒有在等待I/O操作的結果
  • 它沒有主動進入等待狀態(也就是沒有調用’wait’)
  • 沒有被停止(例如:等待終止)

在Linux中,進程分爲三種狀態,一種是阻塞的進程blocked process,一種是可運行的進程runnable process,另外就是正在運行的進程running process

進程可運行狀態時,它處在一個運行隊列run queue中,與其他可運行進程爭奪CPU時間。 系統的load是指正在運行和準備好運行的進程的總數。比如現在系統有2個正在運行的進程,3個可運行進程,那麼系統的load就是5。load average就是一定時間內的load數量。

一般來說只要每個CPU的當前活動進程數不大於3那麼系統的性能就是良好的,如果每個CPU的任務數大於5,那麼就表示這臺機器的性能有嚴重問題。

CPU使用率高並不總是意味着CPU工作繁忙,它有可能是正在等待其他子系統。在進行性能分析時,將所有子系統當做一個整體來看是非常重要的,因爲在子系統中可能會出現瀑布效應。衡量CPU 系統負載的指標是load,load 就是對計算機系統能夠承擔的多少負載的度量,簡單的說是進程隊列的長度。簡單的例子比如食堂有五個窗口,當有小於五個學生來打飯,五個窗口都能及時處理,但是當學生個數超過5個,必然會出現等待的學生。請求大於當前的處理能力,會出現等待,引起load升高。
Load Average 就是一段時間(1min,5min,15min)內平均Load。平均負載的最佳值是1,這意味着每個進程都可以在一個完整的CPU 週期內完成。

cpu load高的排查思路

1. 首先排查哪些進程cpu佔用率高。 通過命令 ps ux

在這裏插入圖片描述

2. 查看對應java進程的每個線程的CPU佔用率。通過命令:ps -Lp 15047 cu

在這裏插入圖片描述

3. 追蹤線程內部,查看load過高原因。通過命令:jstack 15047。

或者打印線程 jstack pidof java > stack.out

查找到對應的threadid, 再反查代碼。

一般經驗

cpu load的飆升,一方面可能和full gc的次數增大有關,一方面可能和死循環有關係

數據庫系統load高的一般原因

  1. 業務併發調用全表掃描/帶有order by 排序的SQL語句。

  2. SQL語句沒有合適索引/執行計劃出錯/update/delete where掃描全表,阻塞其他訪問相同表的sql執行.SQL語句沒有合適索引/執行計劃出錯/update/delete
    where掃描全表,阻塞其他訪問相同表的sql執行。

  3. 存在秒殺類似的業務比如聚划算10點開團或者雙十一秒殺,瞬時海量訪問給數據庫帶來衝擊。存在秒殺類似的業務比如聚划算10點開團或者雙十一秒殺,瞬時海量訪問給數據庫帶來衝擊。

  4. 數據庫做邏輯備份(需要全表掃描)或者多實例的壓縮備份(壓縮時需要大量的cpu計算,會導致系統服務器load飆高)數據庫做邏輯備份(需要全表掃描)或者多實例的壓縮備份(壓縮時需要大量的cpu計算,會導致系統服務器load飆高)。

  5. 磁盤寫入方式改變 比如有writeback 變爲 write through磁盤寫入方式改變 比如有writeback 變爲 write through。

    RAID卡都有寫cache(Battery Backed Write Cache),寫cache對IO性能的提升非常明顯,因爲掉電會丟失數據,所以必須由電池提供支持。
    電池會定期充放電,一般爲90天左右,當發現電量低於某個閥值時,會將寫cache策略從writeback置爲writethrough,相當於寫cache會失效,這時如果系統有大量的IO操作,可能會明顯感覺到IO響應速度變慢,cpu
    隊列堆積系統load 飆高。

判別和處理load高問題

一般根據cpu數量去判斷,也就是Load平均要小於CPU的數量,負載的正常值在不同的系統中有着很大的差別。在單核處理器的工作站中,1或2都是可以接受的。多核處理器的服務器(比如24核)上,load 會到達20 ,甚至更高。

a) 數據庫層面

  1. top -u mysql -c 檢查當前佔用cpu資源最多的進程命令。-c 是爲了顯示出進程對應的執行命令語句,方便查看是什麼操作導致系統load飆高。
  2. 根據不同的情況獲取pid 或者MySQL的端口號
  3. 如果是MySQL 數據庫服務導致laod 飆高,則可以使用如下命令
    show processlist;
    SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND <> ‘sleep’ AND TIME>100;

    orzdba 工具檢查邏輯讀/thread active的值。用法orzdba --help
    orztop 工具檢查當前正在執行的慢sql,用法orztop -P $port
  4. 獲取異常的sql之後,剩下的比較好解決了。結合第一部分中的幾條原因
    1. 選擇合適的索引
    2. 調整sql 語句 比如對應order by 分頁採用延遲關聯
    3. 業務層面增加緩存,減少對數據庫的直接訪問等業務層面增加緩存,減少對數據庫的直接訪問等

b) OS 系統層面 檢查系統IO

使用iostat 命令查看r/s(讀請求),w/s(寫請求),avgrq-sz(平均請求大小),await(IO等待), svctm(IO響應時間)

r/s ,w/s是每秒讀/寫請求的次數。

util是設備的利用率。如果它接近100%,通常說明設備能力趨於飽和(並不絕對,比如設備有寫緩存)。有時候可能會出現大於100%的情況,這多半是計算時四捨五入引起的。
svctm是平均每次請求的服務時間。這裏有一個公式:(r/s+w/s)*(svctm/1000)=util。舉例子:如果util達到100%,那麼此時 svctm=1000/(r/s+w/s),假設IOPS是1000,則svctm大概在1毫秒左右,如果長時間大於這個數值,說明系統出了問題。
await是平均每次請求的等待時間。這個時間包括了隊列時間和服務時間,也就是說,一般情況下,await大於svctm,它們的差值越小,隊列時間越短,反之差值越大,隊列時間越長,說明系統出了問題。
avgqu-sz是平均請求隊列的長度。毫無疑問,隊列長度越短越好。

參考資料

http://blog.csdn.net/u011183653/article/details/19489603
http://blog.itpub.net/22664653/viewspace-1262635/
流年素心 http://www.cnblogs.com/lddbupt/

站在巨人的肩膀上

本文轉載的網絡地址
https://www.cnblogs.com/lddbupt/p/5779655.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章