如何使用效能分析工具觀察cpu效能指標
前言:為了更好配置分散式儲存叢集的執行引數,使用效能分析工具觀察業務環境是一種必要的手段
op 或者 uptime
02:34:03 //當前時間
up 2 days, 20:14 //系統執行時間
1 user //正在登入使用者數
load average: 0.63, 0.83, 0.88
依次則是過去 1 分鐘、5 分鐘、15 分鐘的平均負載(Load Average)
平均負載是指單位時間內,系統處於可執行狀態和不可中斷狀態的平均程序數,也就是平均活躍程序數,它和 CPU 使用率並沒有直接關係,所以,它不僅包括了正在使用 CPU 的程序,還包括等待 CPU 和等待 I/O 的程序。
可執行狀態
可執行狀態的程序,是指正在使用 CPU 或者正在等待 CPU 的程序,也就是我們常用 ps 命令看到的,處於 R 狀態(Running 或 Runnable)的程序
可中斷的睡眠狀態的程序會睡眠直到某個條件變為真,如產生一個硬體中斷、釋放程序正在等待的系統資源或是傳遞一個訊號都可以是喚醒程序的條件。
不可中斷狀態
不可中斷狀態的程序則是正處於核心態關鍵流程中的程序,並且這些流程是不可打斷的
那就是把訊號傳遞到這種睡眠狀態的程序不能改變它的狀態,也就是說它不響應訊號的喚醒。
比如,當一個程序向磁碟讀寫資料時,為了保證資料的一致性,在得到磁盤迴復前,它是不能被其他程序或者中斷打斷的,這個時候的程序就處於不可中斷狀態。如果此時的程序被打斷了,就容易出現磁碟資料與程序資料不一致的問題。所以,不可中斷狀態實際上是系統對程序和硬體裝置的一種保護機制。
既然平均的是活躍程序數,那麼最理想的,就是每個 CPU 上都剛好執行著一個程序,這樣每個 CPU 都得到了充分利用。
比如當平均負載為 2 時,意味著什麼呢?
1.在只有 2 個 CPU 的系統上,意味著所有的 CPU 都剛好被完全佔用。
2.在 4 個 CPU 的系統上,意味著 CPU 有 50% 的空閒。
3.而在只有 1 個 CPU 的系統中,則意味著有一半的程序競爭不到 CPU。 ====》 (平均負載比cpu個數大,過載 )
所以 平均負載最理想的情況是等於 CPU 個數
grep 'model name' /proc/cpuinfo | wc -l //可檢視cpu數目 12 //12核
如何觀察數值
//假設單核情況
[email protected]:~# uptime
09:28:31 up 1 day, 10:31, 2 users, load average: 1.96, 1.29, 1.59
假設是單核情況下, 1分鐘下來有96%超載,5分鐘下來有29%超載,15分鐘下來有59%超載
1.當三者相差不大,說明系統的平均負載穩定。
2.當前1分鐘比後兩者小的時候,說明系統趨於降低
3.如果1分鐘的值遠大於 15 分鐘的值,就說明最近 1 分鐘的負載在增加
經驗值之談,一旦平均負載達到CPU數量的前後 75%左右,需要排查負載高的問題。
平均負載與 CPU 使用率區別
CPU 使用率,是單位時間內 CPU 繁忙情況的統計,跟平均負載並不一定完全對應
CPU使用率:單位時間內cpu繁忙情況的統計
情況1:CPU密集型程序,CPU使用率和平均負載基本一致
情況2:IO密集型程序,平均負載升高,CPU使用率不一定升高
情況3:大量等待CPU的程序排程,平均負載升高,CPU使用率也升高
場景模擬
借用iostat mpstat pidstat可以分析出平均負載升高的原因。
模擬一下使用場景
[email protected]:~# apt install sysstat //常用的 Linux 效能工具,用來監控和分析系統的效能,包含兩個命令 mpstat 和 pidsta
[email protected]:~# apt install stress //一個 Linux 系統壓力測試工具
前提環境:
機器配置:4 CPU,8GB 記憶體。
[email protected]:~# uptime
11:36:37 up 13 days, 29 min, 3 users, load average: 0.06, 0.06, 0.01
CPU 的使用者層(%usr)使用率;
CPU 的系統層(%sys)使用率;
CPU 的 I/0 - 等待(%iowait);
CPU 的空閒率(%idle);
首先,我們在第一個終端執行 stress 命令,模擬一個 CPU 使用率 100% 的CPU 密集型程序場景:
//一終端執行
[email protected]:~# stress --cpu 4 --timeout 555
stress: info: [4563] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
//另一終端
[email protected]:~# watch -d uptime
Every 2.0s: uptime xxxx: Tue Dec 22 11:43:36 2020
11:43:36 up 13 days, 36 min, 3 users, load average: 4.13, 1.28, 0.46
// 另一終端2
//-P ALL 表示監控所有CPU,後面數字5表示間隔5秒後輸出一組資料
[email protected]:~# mpstat -P ALL 5
11:45:26 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11:45:31 AM all 99.65 0.00 0.25 0.00 0.00 0.10 0.00 0.00 0.00 0.00
11:45:31 AM 0 99.40 0.00 0.40 0.00 0.00 0.20 0.00 0.00 0.00 0.00
11:45:31 AM 1 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
11:45:31 AM 2 99.80 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00
11:45:31 AM 3 99.80 0.00 0.00 0.00 0.00 0.20 0.00 0.00 0.00 0.00
//從這裡可以明顯看到,stress 程序的 CPU 使用率接近 100%。
[email protected]:~# pidstat -u 5 1
Linux 4.15.0-66-generic (xxxx) 12/22/2020 _x86_64_ (4 CPU)
11:48:58 AM UID PID %usr %system %guest %wait %CPU CPU Command
11:49:03 AM 0 2049 0.00 0.20 0.00 0.00 0.20 2 kworker/2:0
11:49:03 AM 64045 3358 0.60 0.20 0.00 0.00 0.80 3 ceph-mon
11:49:03 AM 0 4564 98.41 0.20 0.00 1.39 98.61 0 stress
11:49:03 AM 0 4565 98.81 0.00 0.00 0.99 98.81 1 stress
11:49:03 AM 0 4566 98.21 0.00 0.00 1.39 98.21 0 stress
11:49:03 AM 0 4567 99.20 0.00 0.00 0.60 99.20 2 stress
11:49:03 AM 0 5131 0.20 0.20 0.00 0.40 0.40 0 watch
11:49:03 AM 0 7419 0.20 0.40 0.00 0.00 0.60 3 pidstat
11:49:03 AM 0 26649 0.00 0.20 0.00 0.00 0.20 0 kworker/0:1
11:49:03 AM 0 26658 0.20 0.20 0.00 0.20 0.40 1 sshd
11:49:03 AM 64045 30555 0.60 0.00 0.00 0.00 0.60 1 ceph-osd
//
可以從 load average: 4.13 以及 mpstat 的usr 看得出負載場景基本符合CPU 密集型程序 ,pidstat可以看得出是 stress 導致佔用率過高。
然後模擬一個I/O 密集型程序
//一終端執行
//[email protected]:~# stress -i 1 --timeout 600 // 因為 stress 使用的sync系統呼叫,重新整理緩衝區到磁碟。有可能因緩衝區資料量小無法看到io_wait明顯變化
[email protected]:~# stress-ng -i 1 --hdd 1 --timeout 555
stress-ng: info: [9211] dispatching hogs: 1 io, 1 hdd
//另一終端
[email protected]:~# watch -d uptime
16:46:09 up 13 days, 5:38, 3 users, load average: 2.91, 2.56, 1.10
// 另一終端2
//-P ALL 表示監控所有CPU,後面數字5表示間隔5秒後輸出一組資料
[email protected]:~# mpstat -P ALL 5
Linux 4.15.0-66-generic (ECSab169d) 12/22/2020 _x86_64_ (4 CPU)
04:44:02 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
04:44:07 PM all 1.35 0.00 29.50 26.74 0.00 0.21 0.52 0.00 0.00 41.68
04:44:07 PM 0 2.05 0.00 30.12 26.23 0.00 0.20 0.61 0.00 0.00 40.78
04:44:07 PM 1 0.40 0.00 30.51 51.72 0.00 0.00 0.81 0.00 0.00 16.57
04:44:07 PM 2 0.84 0.00 19.29 19.08 0.00 0.00 0.42 0.00 0.00 60.38
04:44:07 PM 3 1.96 0.00 38.26 8.48 0.00 0.65 0.22 0.00 0.00 50.43
[email protected]:~# pidstat -u 5 1
04:43:15 PM UID PID %usr %system %guest %wait %CPU CPU Command
04:43:20 PM 0 388 0.00 0.20 0.00 0.00 0.20 0 kworker/0:1H
04:43:20 PM 0 11841 0.00 2.00 0.00 0.00 2.00 1 kworker/1:2
04:43:20 PM 0 12449 0.00 5.40 0.00 0.40 5.40 1 stress-ng-io
04:43:20 PM 0 12450 2.60 60.20 0.00 0.80 62.80 0 stress-ng-hdd
04:43:20 PM 0 22527 0.20 0.20 0.00 0.00 0.40 1 sshd
04:43:20 PM 64045 30555 0.20 0.40 0.00 0.00 0.60 1 ceph-osd
從這裡可以看到,1 分鐘的平均負載會慢慢增加到 2.91,其中一個 CPU 的系統 CPU 使用率升高到了 30.51,而 iowait 高達 51.72%。這說明,平均負載的升高是由於 iowait 的升高,pidstat 定位到stress程序。
模擬一個大量程序場景
//一終端執行
[email protected]:~# stress -c 8 --timeout 555
17:00:26 up 13 days, 5:53, 3 users, load average: 7.90, 4.95, 3.04
//另一終端
[email protected]:~# watch -d uptime
17:00:49 up 13 days, 5:53, 3 users, load average: 7.94, 5.20, 3.17
[email protected]:~# pidstat -u 5 1
04:43:15 PM UID PID %usr %system %guest %wait %CPU CPU Command
04:43:20 PM 0 388 0.00 0.20 0.00 0.00 0.20 0 kworker/0:1H
04:43:20 PM 0 11841 0.00 2.00 0.00 0.00 2.00 1 kworker/1:2
04:43:20 PM 0 12449 0.00 5.40 0.00 0.40 5.40 1 stress-ng-io
04:43:20 PM 0 12450 2.60 60.20 0.00 0.80 62.80 0 stress-ng-hdd
04:43:20 PM 0 22527 0.20 0.20 0.00 0.00 0.40 1 sshd
04:43:20 PM 64045 30555 0.20 0.40 0.00 0.00 0.60 1 ceph-osd
05:01:33 PM UID PID %usr %system %guest %wait %CPU CPU Command
05:01:38 PM 64045 3358 0.40 0.20 0.00 0.00 0.60 3 ceph-mon
05:01:38 PM 0 5131 0.60 0.20 0.00 0.60 0.80 1 watch
05:01:38 PM 0 9303 0.00 0.20 0.00 0.00 0.20 2 kworker/u8:3
05:01:38 PM 0 13169 0.00 0.20 0.00 0.00 0.20 0 kworker/0:2
05:01:38 PM 0 18138 48.91 0.00 0.00 51.09 48.91 1 stress
05:01:38 PM 0 18139 49.11 0.00 0.00 50.70 49.11 2 stress
05:01:38 PM 0 18140 48.71 0.00 0.00 50.89 48.71 0 stress
05:01:38 PM 0 18141 50.10 0.00 0.00 49.50 50.10 3 stress
05:01:38 PM 0 18142 47.91 0.00 0.00 51.89 47.91 3 stress
05:01:38 PM 0 18143 49.11 0.00 0.00 51.09 49.11 1 stress
05:01:38 PM 0 18144 52.29 0.00 0.00 47.71 52.29 0 stress
05:01:38 PM 0 18145 49.30 0.00 0.00 50.70 49.30 2 stress
05:01:38 PM 0 20608 0.00 0.20 0.00 0.20 0.20 0 pidstat
05:01:38 PM 0 22527 0.00 0.20 0.00 0.00 0.20 2 sshd
05:01:38 PM 64045 30555 0.40 0.00 0.00 0.00 0.40 1 ceph-osd
可以看出,8 個程序在爭搶 4 個 CPU,每個程序等待 CPU 的時間(也就是程式碼塊中的 %wait 列)高達 50%。這些超出 CPU 計算能力的程序,最終導致 CPU 過載。
總結
1.CPU密集型程序: 檢視 mpstat 是否存在某個CPU %usr 很高但是iowait 很低 , pidstat 定位具體程序(瓶頸不在io)
2.IO密集型程序: mpstat 觀察是否有某個cpu的%iowait很高,同時%usr也較高, pidstat 定位具體程序
3.大量程序 : 觀察 mpstat 有可能iowait 很低, 但是從 pidstat 看出%wait很高,側面表現出程序出現競爭cpu
用到命令
lscpu、 grep ‘model name’ /proc/cpuinfo | wc -l : cpu核數
watch -d uptime : 持續觀察平均負載
pidstat -u 5 1 : 監測程序對應負載狀態,程序效能分析工具
mpstat -P ALL 5 : cpu總體狀態 多核cpu效能分析工具,-P ALL監視所有cpu
strees : -c 產生多個worker程序;—cpu-method 使用哪種演算法來執行壓力測試,包括pi, crc16, fft等等,all選擇全部;—sock 呼叫socket相關函式產生壓力; -t, —timeout 等待xx微秒後才開始執行;-i, —io N spawn N workers spinning on sync()