如何理解CPU負載以及分析


Cpu負載(load average)介紹

平均負載是指單位時間內,系統處於可運行狀態和不可中斷狀態的平均進程數,也就是平均活躍進程數,它和 CPU 使用率並沒有直接關系。所謂可運行狀態的進程,是指正在使用 CPU 或者正在等待 CPU 的進程,也就是我們常用 ps 命令看到的,處於 R 狀態(Running 或 Runnable)的進程。不可中斷狀態的進程則是正處於內核態關鍵流程中的進程,並且這些流程是不可打斷的,比如最常見的是等待硬件設備的 I/O 響應,也就是我們在 ps 命令中看到的 D 狀態(Uninterruptible Sleep,也稱為 Disk Sleep)的進程。比如,當一個進程向磁盤讀寫數據時,為了保證數據的一致性,在得到磁盤回復前,它是不能被其他進程或者中斷打斷的,這個時候的進程就處於不可中斷狀態。如果此時的進程被打斷了,就容易出現磁盤數據與進程數據不一致的問題。所以,不可中斷狀態實際上是系統對進程和硬件設備的一種保護機制。因此,你可以簡單理解為,平均負載其實就是平均活躍進程數。平均活躍進程數,直觀上的理解就是單位時間內的活躍進程數,但它實際上是活躍進程數的指數衰減平均值。這個“指數衰減平均”的詳細含義你不用計較,這只是系統的一種更快速的計算方式,你把它直接當成活躍進程數的平均值也沒問題。既然平均的是活躍進程數,那么最理想的,就是每個 CPU 上都剛好運行着一個進程,這樣每個 CPU 都得到了充分利用。比如當平均負載為 2 時,意味着什么呢?在只有 2 個 CPU 的系統上,意味着所有的 CPU 都剛好被完全占用。在 4 個 CPU 的系統上,意味着 CPU 有 50% 的空閑。而在只有 1 個 CPU 的系統中,則意味着有一半的進程競爭不到 CPU。

負載查看方法:

w:查看能查到在線信息和負載情況

uptime:能查到負載信息、

top:除了查看負載以外,還能動態查看其他很多性能信息,比如進程 cpu 使用率、內存使用信息、進程狀態等

load average:1分鍾負載,5分鍾負載,15分鍾負載

實際上,都要看。三個不同時間間隔的平均值,其實給我們提供了,分析系統負載趨勢的數據來源,讓我們能更全面、更立體地理解目前的負載狀況。打個比方,就像初秋時北京的天氣,如果只看中午的溫度,你可能以為還在 7 月份的大夏天呢。但如果你結合了早上、中午、晚上三個時間點的溫度來看,基本就可以全方位了解這一天的天氣情況了。同樣的,前面說到的 CPU 的三個負載時間段也是這個道理。

[root@k8sm01 ~]# w
 10:59:03 up 1 min, 1 user, load average: 0.94, 0.48, 0.18
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 10.0.2.218 10:58 7.00s 0.04s 0.00s w
————————————————————————————————
[root@k8sm01 ~]# uptime 
 10:59:12 up 1 min, 1 user, load average: 0.80, 0.46, 0.18
————————————————————————————————
[root@k8sm01 ~]# top
top - 10:59:26 up 1 min, 1 user, load average: 0.62, 0.44, 0.17
Tasks: 124 total, 1 running, 123 sleeping, 0 stopped, 0 zombie
%Cpu(s): 3.1 us, 0.0 sy, 0.0 ni, 96.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 3861372 total, 3217472 free, 250288 used, 393612 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 3378012 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
 1 root 20 0 126132 4588 2580 S 0.0 0.1 0:03.03 systemd 
 2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd

合理負載判定:

個人認為,只要不要超過標准負載的70%就可以說明我們服務器是正常的,比如負載=N。CPU個數=C。通過以下公式得到你的負載處於什么階段:

0<N/C*100%<50%<C :說明CPU負載比較低
0<50%<N/C*100%<100%<=C :說明CPU負載比較合理
C<N/C*100%<170%: 說明CPU負載很忙,已經出現任務等待現象
C<N/C*100%<200%: 說明CPU負載非常嚴重,等待現場加劇
C<200%<N/C*100%: CPU嚴重超負荷,有可能導致部分服務不可用,或者服務器重啟事件;

另一種判定

如果 1 分鍾、5 分鍾、15 分鍾的三個值基本相同,或者相差不大,那就說明系統負載很平穩。但如果 1 分鍾的值遠小於 15 分鍾的值,就說明系統最近 1 分鍾的負載在減少,而過去 15 分鍾內卻有很大的負載。反過來,如果 1 分鍾的值遠大於 15 分鍾的值,就說明最近 1 分鍾的負載在增加,這種增加有可能只是臨時性的,也有可能還會持續增加下去,所以就需要持續觀察。一旦 1 分鍾的平均負載接近或超過了 CPU 的個數,就意味着系統正在發生過載的問題,這時就得分析調查是哪里導致的問題,並要想辦法優化了。這里我再舉個例子,假設我們在一個單 CPU 系統上看到平均負載為 1.73,0.60,7.98,那么說明在過去 1 分鍾內,系統有 73% 的超載,而在 15 分鍾內,有 698% 的超載,從整體趨勢來看,系統的負載在降低。

CPU個數查看方法:

[root@k8sm01 ~]# grep 'model name' /proc/cpuinfo | wc -l
2

平均負載與 CPU 使用率

現實工作中,我們經常容易把平均負載和 CPU 使用率混淆,所以在這里,可能你會疑惑,既然平均負載代表的是活躍進程數,那平均負載高了,不就意味着 CPU 使用率高嗎?我們還是要回到平均負載的含義上來,平均負載是指單位時間內,處於可運行狀態和不可中斷狀態的進程數。
所以,它不僅包括了正在使用 CPU 的進程,還包括等待 CPU 和等待 I/O 的進程。 • CPU 密集型進程,使用大量 CPU 會導致平均負載升高,此時這兩者是一致的; • I/O 密集型進程,等待 I/O 也會導致平均負載升高,但 CPU 使用率不一定很高; • 大量等待 CPU 的進程調度也會導致平均負載升高,此時的 CPU 使用率也會比較高。

基於負載案列分析:

我的按分析機器信息如下

[root@k8sm01 ~]# echo "操作系統: `cat /etc/redhat-release`" ;echo "CPU 個數: `grep 'model name' /proc/cpuinfo | wc -l`";echo -e "硬盤信息如下: \n`df -hP`";echo -e "內存信息如下: \n`free -m` "
------------------以上是執行的命令,以下是獲得的結果--------------------------------------------------------------------------
操作系統: CentOS Linux release 7.7.1908 (Core)
CPU 個數: 2
硬盤信息如下: 
文件系統 容量 已用 可用 已用% 掛載點
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 12M 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/mapper/centos-root 27G 2.9G 25G 11% /
/dev/sda1 1014M 153M 862M 15% /boot
tmpfs 378M 0 378M 0% /run/user/0
內存信息如下: 
total used free shared buff/cache available
Mem: 3770 271 3083 11 415 3261
Swap: 0 0 0

使用到的分析工具包stress 和 sysstat

stress :是一個 Linux 系統壓力測試工具,這里我們用作異常進程模擬平均負載升高的場景。

sysstat: 包含了常用的 Linux 性能工具iostat vmstat mpstat pidstat,用來監控和分析系統的性能。我們的案例會用到這個包的兩個命令 mpstat 和 pidstat。

安裝以上兩個工具,如果是ubuntu  apt install stress sysstat

[root@k8sm01 ~]# yum  -y install stress sysstat

 安裝完成后開啟三個終端TTY1 TTY2 TTY3

基於CPU 密集型進程分析:

TTY1:執行  taskset  -c 1 stress --cpu 1 --timeout 600

[root@k8sm01 ~]# taskset  -c 1 stress --cpu 1 --timeout 600
 

 命令解釋:

-n,顯示已完成的指令情況
-t,運行N秒后停止
--backoff,等待N微秒后開始運行
-c,模擬N個CPU密集型進程(進程主要調用sqrt()函數計算隨機數的平方根)
-i,模擬N個I/O密集型進程(進程調用sync()將內存緩沖刷新到磁盤上)
-m,模擬N個內存壓力測試進程,進程不斷調用malloc/free
--vm-bytes,指定上述產生進程的malloc的大小,默認256M
--vm-stride ,這項沒懂?
--vm-hang ,表示分配的內存經過N秒再釋放
--vm-keep,保持分配的內存,不釋放或者重新分配
-d,模擬N個進程做write/unlink操作
--hdd-bytes,指定硬盤寫操作的進程寫的文件大小
--hdd-noclean,寫入的文件不刪除

TTY2:執行watch -d uptime

[root@k8sm01 ~]# watch -d uptime

 

發現當前CPU一分以內都是接近於1

TTY3:執行mpstat -P ALL 5

[root@k8sm01 ~]# mpstat -P ALL 5
15時03分10秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
15時03分15秒 all 49.75 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 50.05
15時03分15秒 0 0.20 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.60
15時03分15秒 1 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

 

從終端二中可以看到,1 分鍾的平均負載會慢慢增加到 1.00,而從終端三中還可以看到,正好有一個 CPU 的使用率為 100%,但它的 iowait 只有 0。這說明,平均負載的升高正是由於 CPU 使用率為 100% 。

那么,到底是哪個進程導致了 CPU 使用率為 100% 呢?你可以新建一個終端使用 pidstat或者來查詢:

[root@k8sm01 ~]# pidstat -u  2 3
#每兩秒刷新 共3組數據
15時10分44秒 UID PID %usr %system %guest %CPU CPU Command
15時10分46秒 0 1254 0.00 0.50 0.00 0.50 0 vmtoolsd
15時10分46秒 0 24078 99.50 0.00 0.00 99.50 1 stress
15時10分46秒 0 24368 0.00 0.50 0.00 0.50 0 pidstat
15時10分46秒 UID PID %usr %system %guest %CPU CPU Command
15時10分48秒 0 1254 0.50 0.00 0.00 0.50 0 vmtoolsd
15時10分48秒 0 24078 100.00 0.00 0.00 100.00 1 stress
15時10分48秒 0 24368 0.50 0.50 0.00 1.00 0 pidstat
15時10分48秒 UID PID %usr %system %guest %CPU CPU Command
15時10分50秒 0 476 0.00 0.50 0.00 0.50 0 xfsaild/dm-0
15時10分50秒 0 557 0.50 0.00 0.00 0.50 0 systemd-journal
15時10分50秒 0 1548 0.50 0.00 0.00 0.50 0 containerd
15時10分50秒 0 19493 0.00 0.50 0.00 0.50 0 sshd
15時10分50秒 0 24078 100.00 0.00 0.00 100.00 1 stress
平均時間: UID PID %usr %system %guest %CPU CPU Command
平均時間: 0 476 0.00 0.17 0.00 0.17 - xfsaild/dm-0
平均時間: 0 557 0.17 0.00 0.00 0.17 - systemd-journal
平均時間: 0 1254 0.17 0.17 0.00 0.33 - vmtoolsd
平均時間: 0 1548 0.17 0.00 0.00 0.17 - containerd
平均時間: 0 19493 0.00 0.17 0.00 0.17 - sshd
平均時間: 0 24078 99.83 0.00 0.00 99.83 - stress
平均時間: 0 24368 0.17 0.33 0.00 0.50 - pidstat

發現stress使用率占用了100%

通過top (輸入top 在按下大P-cpu使用率排序)

[root@k8sm01 ~]# top

 I/O 密集型進程

首先還是運行 stress 命令,但這次模擬 I/O 壓力,即不停地執行 sync:

TTY1:

[root@k8sm01 ~]# taskset -c 1 stress -i 1 --timeout 600

TTY2:

[root@k8sm01 ~]# watch -d uptime

TTY3:

[root@k8sm01 ~]# mpstat -P ALL 5
Linux 3.10.0-1062.el7.x86_64 (k8sm01.com) 2020年06月20日 _x86_64_ (2 CPU)
16時46分57秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
16時47分02秒 all 0.11 0.00 30.17 0.00 0.00 0.00 0.00 0.00 0.00 69.72
16時47分02秒 0 0.00 0.00 22.47 0.00 0.00 0.00 0.00 0.00 0.00 77.53
16時47分02秒 1 0.22 0.00 37.92 0.00 0.00 0.00 0.00 0.00 0.00 61.86
16時47分02秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
16時47分07秒 all 1.10 0.00 31.35 0.11 0.00 0.11 0.00 0.00 0.00 67.33
16時47分07秒 0 1.97 0.00 23.41 0.00 0.00 0.22 0.00 0.00 0.00 74.40
16時47分07秒 1 0.22 0.00 39.21 0.22 0.00 0.22 0.00 0.00 0.00 60.13
平均時間: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
平均時間: all 0.61 0.00 30.76 0.06 0.00 0.06 0.00 0.00 0.00 68.52
平均時間: 0 0.99 0.00 22.94 0.00 0.00 0.11 0.00 0.00 0.00 75.96
平均時間: 1 0.22 0.00 38.56 0.11 0.00 0.11 0.00 0.00 0.00 60.99

從這里可以看到,1 分鍾的平均負載會慢慢增加到 1.21,指定的CPU 的系統 CPU 使用率升高到了 38.56%,可能是我的本地盤是SSD,所以沒出現iowait .但是發現idle time剩余60.99%

那么到底是哪個進程,導致 系統CPU使用率這么高呢?我們還是用 pidstat 來查詢

[root@k8sm01 ~]#  pidstat -u 5 1

Linux 3.10.0-1062.el7.x86_64 (k8sm01.com) 2020年06月20日 _x86_64_ (2 CPU)

16時52分40秒 UID PID %usr %system %guest %CPU CPU Command
16時52分45秒 0 9 0.00 0.20 0.00 0.20 1 rcu_sched
16時52分45秒 0 477 0.00 0.20 0.00 0.20 0 kworker/0:1H
16時52分45秒 0 1548 0.20 0.20 0.00 0.40 0 containerd
16時52分45秒 0 37224 0.00 29.34 0.00 29.34 0 kworker/u256:1
16時52分45秒 0 38831 0.20 75.45 0.00 75.65 1 stress
16時52分45秒 0 38832 0.00 33.13 0.00 33.13 0 kworker/u256:0
16時52分45秒 0 38871 0.00 0.20 0.00 0.20 1 pidstat

平均時間: UID PID %usr %system %guest %CPU CPU Command
平均時間: 0 9 0.00 0.20 0.00 0.20 - rcu_sched
平均時間: 0 477 0.00 0.20 0.00 0.20 - kworker/0:1H
平均時間: 0 1548 0.20 0.20 0.00 0.40 - containerd
平均時間: 0 37224 0.00 29.34 0.00 29.34 - kworker/u256:1
平均時間: 0 38831 0.20 75.45 0.00 75.65 - stress
平均時間: 0 38832 0.00 33.13 0.00 33.13 - kworker/u256:0
平均時間: 0 38871 0.00 0.20 0.00 0.20 - pidstat

可以發現,還是 stress 進程導致的。

基於大量進程的場景

當系統中運行進程超出 CPU 運行能力時,就會出現等待 CPU 的進程。比如,我們還是使用 stress,但這次模擬的是 >=4個進程:

[root@k8sm01 ~]# stress -c 4 --timeout 600
[root@k8sm01 ~]# watch -d uptime

負載會維持在4左右

查看CPU使用情況

[root@k8sm01 ~]# mpstat -P ALL 5

2個CPU都已經跑滿了

[root@k8sm01 ~]#  pidstat -u 5 

查看是由於4個 stress進程導致


免責聲明!

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



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