怎么理解linux的平均負載及平均負載高后的排查工具


什么是平均負載

平均負載可以對於我們來說及熟悉又陌生,但我們問平均負載是什么,但大部分人都回答說平均負載不就是單位時間內CPU使用率嗎?其實並不是這樣的,如果可以的話,可以 man uptime 來了解一下平均負載的詳細信息。

簡單的說平均負載是指單位時間內,系統處於可運行狀態和不可中斷狀態的平均進程數,也就是說平均活躍進程數,它和CPU使用率並沒有直接關系。這里解釋一下可運行狀態和不可中斷這兩個詞。

可運行狀態:

  • 指正在使用CPU或者正在等待CPU的進程,我們使用ps命令查看處於R狀態的進程

不可中斷狀態:

  • 進程則是正處於內核態關鍵流程中的進程,並且這些流程是不可中斷的。例如:常見的等待硬件設備I/O的響應,也就是我們在ps命令查看處於D狀態的進程

比如,當一個進程向磁盤讀寫數據時,為了保證數據的一致性,在得到磁盤回復前,它是不能被其他進程中斷或者打斷的,這個時候的進程處於不可中斷狀態,如果此時的進程被打斷了,就容易出現磁盤數據和進程數據不一致的問題。

所以,不可中斷狀態實際上是系統進程和硬件設備的一種保護機制。

因此,你可以簡單理解為,平均負載就是平均活躍進程數。平均活躍進程數,直觀上的理解就是單位時間內的活躍進程數,但它實際上是活躍進程數的指數衰減平均值。既然是平均活躍進程數,那么理想狀態,就是每個CPU上都剛好運行着一個進程,這樣每個CPU都會得到充分的利用。例如平均負載為2時,意味着什么呢?

  • 在只有2個CPU的系統上,意味着所有的CPU剛好被完全占用
  • 在4個CPU的系統上,意味着CPU有50%的空閑
  • 而在只有1個CPU的系統上,則意味着有一半的進程競爭不到CPU

平均負載和CPU使用率

現實工作中,我們經常容易把平均負載和CPU使用率混淆,所以在這里,我也做一個分區。

可能你會疑惑,既然平均負載代表的是活躍進程數,那平均負載高了,不就意味着CPU使用率高嗎?

我們還是要回到平均負載的含義上來,平均負載是指單位時間內,處於可運行狀態和不可中斷狀態的進程數,所以,它不僅包括了正常使用CPU的進程,還包括了等待CPU和等待I/O的進程。

而CPU使用率,是單位時間內CPU的繁忙情況的統計,跟平均負載並不一定完全對應,例如:

  • CPU密集型進程,使用大量CPU會導致平均負載升高,此時這兩者是一致的
  • I/O密集型進程,等待I/O也會導致平均負載升高,但CPU使用率不一定很高
  • 大量等待CPU的進程調度也會導致平均負載升高,此時的CPU使用率會很高

平均負載案例

這里我們需要安裝幾個工具sysstat、stress、stress-ng

這里Centos的sysstat版本會老一點,最好升級到最新版本。手動rpm安裝或者源碼安裝

場景一、CPU密集型

1、運行一個stress命令,模擬一個CPU使用率100%場景

$ stress --cpu 1 --timeout 600

2、開啟第二個終端,uptime查看平均負載的變化情況

$ watch -d uptime
 09:40:35 up 80 days, 18:41,  2 users,  load average: 1.62, 1.10, 0.87

3、開啟第三個終端,mpstat 查看CPU使用率的變化情況

$ mpstat -P ALL 5 20
10:06:37 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
10:06:42 AM  all   31.50    0.00    0.35    0.00    0.00    0.00    0.00    0.00    0.00   68.15
10:06:42 AM    0    1.20    0.00    0.80    0.00    0.00    0.00    0.00    0.00    0.00   98.00
10:06:42 AM    1    7.21    0.00    0.40    0.00    0.00    0.00    0.00    0.00    0.00   92.38
10:06:42 AM    2  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
10:06:42 AM    3   17.43    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00   82.36 #
-P ALL 表示監控所有CPU,后面數字5 表示間隔5秒輸出一次數據

從第二個終端可以看到,1分鍾平均負載增加到1.62,從第三個終端我們可以看到有一個CPU使用率100%,但iowait為0,這說明平均負載的升高正式由CPU使用率為100%

那我們查看是那個進程導致了CPU使用率為100%呢?我們可以使用pidstat來查看:

#每5秒輸出一次數據
$ pidstat -u 5 1 10:08:41 AM UID PID %usr %system %guest %wait %CPU CPU Command 10:08:46 AM 0 1 0.20 0.00 0.00 0.00 0.20 0 systemd 10:08:46 AM 0 599 0.00 1.00 0.00 0.20 1.00 0 systemd-journal 10:08:46 AM 0 1043 0.60 0.00 0.00 0.00 0.60 0 rsyslogd 10:08:46 AM 0 6863 100.00 0.00 0.00 0.00 100.00 3 stress 10:08:46 AM 0 7303 0.20 0.20 0.00 0.00 0.40 2 pidstat

從這里我們可以看到是stress這個進程導致的。

場景二、I/O密集型進程

1、我們使用stress-ng命令,但這次模擬I/O壓力,既不停執行sync:

 

#--hdd表示讀寫臨時文件
#-i 生成幾個worker循環調用sync()產生io壓力 $ stress
-ng -i 4 --hdd 1 --timeout 600

 

2、開啟第二個終端運行uptime查看平均負載情況

$ watch -d uptime 
 10:30:57 up 98 days, 19:39,  3 users,  load average: 1.71, 0.75, 0.69

3、開啟第三個終端運行mpstat查看CPU使用率

$ mpstat -P ALL 5 20
10:32:09 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
10:32:14 AM  all    6.80    0.00   33.75   26.16    0.00    0.39    0.00    0.00    0.00   32.90
10:32:14 AM    0    4.03    0.00   69.57   19.91    0.00    0.00    0.00    0.00    0.00    6.49
10:32:14 AM    1   25.32    0.00    9.49    0.00    0.00    0.95    0.00    0.00    0.00   64.24
10:32:14 AM    2    0.24    0.00   10.87   63.04    0.00    0.48    0.00    0.00    0.00   25.36
10:32:14 AM    3    1.42    0.00   36.93   14.20    0.00    0.28    0.00    0.00    0.00   47.16

從這里可以看到,1分鍾平均負載會慢慢增加到1.71,其中一個CPU的系統CPU使用率升到63.04。這說明,平均負載的升高是由於iowait升高。

那么我們到底是哪個進程導致的呢?我們使用pidstat來查看:

$ pidstat -u 5 1
Average:      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
Average:        0         1    0.00    0.19    0.00    0.00    0.19     -  systemd
Average:        0        10    0.00    0.19    0.00    1.56    0.19     -  rcu_sched
Average:        0       599    0.58    1.75    0.00    0.39    2.33     -  systemd-journal
Average:        0      1043    0.19    0.19    0.00    0.00    0.39     -  rsyslogd
Average:        0      6934    0.00    1.56    0.00    1.17    1.56     -  kworker/2:0-events_power_efficient
Average:        0      7383    0.00    0.39    0.00    0.78    0.39     -  kworker/1:0-events_power_efficient
Average:        0      9411    0.00    0.19    0.00    0.58    0.19     -  kworker/0:0-events
Average:        0      9662    0.00   97.67    0.00    0.19   97.67     -  kworker/u8:0+flush-253:0
Average:        0     10793    0.00    0.97    0.00    1.56    0.97     -  kworker/3:2-mm_percpu_wq
Average:        0     11062    0.00   21.79    0.00    0.19   21.79     -  stress-ng-hdd
Average:        0     11063    0.00    1.95    0.00    1.36    1.95     -  stress-ng-io
Average:        0     11064    0.00    2.72    0.00    0.39    2.72     -  stress-ng-io
Average:        0     11065    0.00    1.36    0.00    1.75    1.36     -  stress-ng-io
Average:        0     11066    0.00    2.72    0.00    0.58    2.72     -  stress-ng-io

可以發現是stress-ng導致的

場景三、大量進程的場景

當系統中運行進程超出CPU運行能力時,就會出現等待CPU的進程。

比如:我們使用stress,但這次模擬8個進程:

$ stress -c 8 --timeout 600

我們的系統只有4顆CPU,這時候要運行8個進程,是明顯不夠的,系統的CPU后嚴重過載,這時候負載值達到了4點多:

$  uptime
 10:56:22 up 98 days, 20:05,  3 users,  load average: 4.52, 2.82, 2.67

接着我們運行pidstat來查看一下進程的情況:

$ pidstat -u 5 1
Linux 5.0.5-1.el7.elrepo.x86_64 (k8s-m1)     07/11/2019     _x86_64_    (4 CPU)

10:57:33 AM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
10:57:38 AM     0         1    0.20    0.00    0.00    0.00    0.20     1  systemd
10:57:38 AM     0       599    0.00    0.99    0.00    0.20    0.99     2  systemd-journal
10:57:38 AM     0      1043    0.60    0.20    0.00    0.00    0.79     1  rsyslogd
10:57:38 AM     0     12927   51.59    0.00    0.00   48.21   51.59     0  stress
10:57:38 AM     0     12928   44.64    0.00    0.00   54.96   44.64     0  stress
10:57:38 AM     0     12929   45.44    0.00    0.00   54.56   45.44     2  stress
10:57:38 AM     0     12930   45.44    0.00    0.00   54.37   45.44     2  stress
10:57:38 AM     0     12931   51.59    0.00    0.00   48.21   51.59     3  stress
10:57:38 AM     0     12932   48.41    0.00    0.00   51.19   48.41     1  stress
10:57:38 AM     0     12933   45.24    0.00    0.00   54.37   45.24     3  stress
10:57:38 AM     0     12934   48.81    0.00    0.00   50.99   48.81     1  stress
10:57:38 AM     0     13083    0.00    0.40    0.00    0.20    0.40     0  pidstat

可以看出,8個進程搶占4顆CPU,每個進程等到CPU時間(%wait)高達50%,這些都超出CPU計算能力的進程,最終導致CPU過載。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM