CPU使用率 Linux 通過 /proc 虛擬文件系統,向用戶空間提供了系統內部狀態的信息,而 /proc/stat 提供的就是系統的 CPU 和任務統計信息 proc process information pseudo file system 查詢 man proc 關鍵指標常用參數 user ...
CPU使用率
Linux 通過 /proc 虛擬文件系統,向用戶空間提供了系統內部狀態的信息,而 /proc/stat 提供的就是系統的 CPU 和任務統計信息
proc - process information pseudo-file system
查詢 man proc
關鍵指標常用參數
- user(通常縮寫為 us),代表用戶態 CPU 時間。註意,它不包括下麵的 nice 時間,但包括了 guest 時間。
- nice(通常縮寫為 ni),代表低優先順序用戶態 CPU 時間,也就是進程的 nice 值被調整為 1-19 之間時的 CPU 時間。這裡註意,nice 可取值範圍是 -20 到 19,數值越大,優先順序反而越低。
- system(通常縮寫為 sys),代表內核態 CPU 時間。
- idle(通常縮寫為 id),代表空閑時間。註意,它不包括等待 I/O 的時間(iowait)。
- iowait(通常縮寫為 wa),代表等待 I/O 的 CPU 時間。
- irq(通常縮寫為 hi),代表處理硬中斷的 CPU 時間。
- softirq(通常縮寫為 si),代表處理軟中斷的 CPU 時間。
- steal(通常縮寫為 st),代表當系統運行在虛擬機中的時候,被其他虛擬機占用的 CPU 時間。
- guest(通常縮寫為 guest),代表通過虛擬化運行其他操作系統的時間,也就是運行虛擬機的 CPU 時間。
- guest_nice(通常縮寫為 gnice),代表以低優先順序運行虛擬機的時間
工具使用
top
[root@k8s ~]# top
top - 15:16:08 up 4 days, 3:12, 1 user, load average: 3.77, 2.88, 2.52
Tasks: 255 total, 1 running, 254 sleeping, 0 stopped, 0 zombie
%Cpu0 : 99.7 us, 0.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 42.3 us, 4.8 sy, 0.0 ni, 50.2 id, 0.7 wa, 0.0 hi, 2.0 si, 0.0 st
KiB Mem : 8173864 total, 753088 free, 3961556 used, 3459220 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 3474088 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3482 root 20 0 2430460 1224 760 S 93.7 0.0 832:50.08 kswapd0
29995 root 20 0 5279240 26508 1760 S 64.2 0.3 25:58.04 tsm
2928 root 20 0 1485424 171912 36504 S 6.6 2.1 317:33.63 kubelet
18035 root 20 0 164248 2480 1612 R 0.3 0.0 0:00.53 top
// top 預設顯示的是所有 CPU 的平均值,這個時候你只需要按下數字 1 ,就可以切換到每個 CPU 的使用率了。
S 列(也就是 Status 列)表示進程的狀態
進程的狀態主要有以下幾個:
- R 是 Running 或 Runnable 的縮寫,表示進程在 CPU 的就緒隊列中,正在運行或者正在等待運行。
- D 是 Disk Sleep 的縮寫,也就是不可中斷狀態睡眠(Uninterruptible Sleep),一般表示進程正在跟硬體交互,並且交互過程不允許被其他進程或中斷打斷。
- Z 是 Zombie 的縮寫,它表示僵屍進程,也就是進程實際上已經結束了,但是父進程還沒有回收它的資源(比如進程的描述符、PID 等)。
- S 是 Interruptible Sleep 的縮寫,也就是可中斷狀態睡眠,表示進程因為等待某個事件而被系統掛起。當進程等待的事件發生時,它會被喚醒併進入 R 狀態。
- I 是 Idle 的縮寫,也就是空閑狀態,用在不可中斷睡眠的內核線程上。前面說了,硬體交互導致的不可中斷進程用 D 表示,但對某些內核線程來說,它們有可能實際上並沒有任何負載,用 Idle 正是為了區分這種情況。要註意,D 狀態的進程會導致平均負載升高, I 狀態的進程卻不會。
pidstat
- 用戶態 CPU 使用率 (%usr);
- 內核態 CPU 使用率(%system);
- 運行虛擬機 CPU 使用率(%guest);
- 等待 CPU 使用率(%wait);
- 總的 CPU 使用率(%CPU)。
[root@k8s ~]# pidstat 1 5
Linux 3.10.0-1062.4.1.el7.x86_64 (instance-010oj085) 04/06/2020 _x86_64_ (2 CPU)
03:23:11 PM UID PID %usr %system %guest %CPU CPU Command
03:23:12 PM 0 1403 0.00 0.97 0.00 0.97 1 kube-controller
03:23:12 PM 0 1638 0.97 0.00 0.00 0.97 1 etcd
03:23:12 PM 0 2492 0.00 1.94 0.00 1.94 1 pidstat
03:23:12 PM 0 2574 0.00 0.97 0.00 0.97 1 hosteye
03:23:12 PM 0 2928 1.94 0.97 0.00 2.91 1 kubelet
03:23:12 PM 0 3233 0.97 0.00 0.00 0.97 1 kube-apiserver
03:23:12 PM 0 3482 100.00 0.00 0.00 100.00 1 kswapd0
perf
perf 是 Linux 2.6.31 以後內置的性能分析工具。它以性能事件採樣為基礎,不僅可以分析系統的各種事件和內核性能,還可以用來分析指定應用程式的性能問題。可以查找熱點函數。
[root@k8s ~]# perf top
Samples: 75K of event 'cycles', 4000 Hz, Event count (approx.): 26597196684 lost: 0/0 drop: 0/0
Overhead Shared Object Symbol
1.57% kswapd0 [.] 0x00000000001c8641
1.10% perf-3482.map [.] 0x00007fdbbf621e8c
0.68% tsm64 [.] 0x000000000002f147
0.61% kswapd0 [.] 0x00000000001c8647
0.60% perf-3482.map [.] 0x00007fdbbf621eb5
- 輸出結果中,第一行包含三個數據,分別是採樣數(Samples)、事件類型(event)和事件總數量(Event count)。
- 第一列 Overhead ,是該符號的性能事件在所有採樣中的比例,用百分比來表示。
- 第二列 Shared ,是該函數或指令所在的動態共用對象(Dynamic Shared Object),如內核、進程名、動態鏈接庫名、內核模塊名等。
- 第三列 Object ,是動態共用對象的類型。比如 [.] 表示用戶空間的可執行程式、或者動態鏈接庫,而 [k] 則表示內核空間。
- 最後一列 Symbol 是符號名,也就是函數名。當函數名未知時,用十六進位的地址來表示。
dstat
dstat可以讓你實時地看到所有系統資源,例如,你能夠通過統計IDE控制器當前狀態來比較磁碟利用率,或者直接通過網路帶寬數值來比較磁碟的吞吐率(在相同的時間間隔內)
[root@k8s ~]# dstat
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
67 3 29 0 0 1|4910B 470k| 0 0 | 0 0 |3645 4917
89 3 6 0 0 3| 0 724k| 394k 267k| 0 0 |5252 4447
90 4 5 0 0 2| 0 140k| 362k 230k| 0 0 |4917 4281
84 3 12 0 0 2| 0 4096B| 287k 196k| 0 0 |4854 4481
84 4 11 0 0 1| 0 216k| 360k 235k| 0 0 |5246 5545
預設輸出信息:
-
CPU狀態:CPU的使用率。這項報告更有趣的部分是顯示了用戶,系統和空閑部分,這更好地分析了CPU當前的使用狀況。如果你看到"wait"一欄中,CPU的狀態是一個高使用率值,那說明系統存在一些其它問題。當CPU的狀態處在"waits"時,那是因為它正在等待I/O設備(例如記憶體,磁碟或者網路)的響應而且還沒有收到。
-
磁碟統計:磁碟的讀寫操作,這一欄顯示磁碟的讀、寫總數。
-
網路統計:網路設備發送和接受的數據,這一欄顯示的網路收、發數據總數。
-
分頁統計:系統的分頁活動。分頁指的是一種記憶體管理技術用於查找系統場景,一個較大的分頁表明系統正在使用大量的交換空間,或者說記憶體非常分散,大多數情況下你都希望看到page in(換入)和page out(換出)的值是0 0。
-
系統統計:這一項顯示的是中斷(int)和上下文切換(csw)。這項統計僅在有比較基線時才有意義。這一欄中較高的統計值通常表示大量的進程造成擁塞,需要對CPU進行關註。你的伺服器一般情況下都會運行運行一些程式,所以這項總是顯示一些數值
pstree
// 指定 pid 查找父進程
[root@k8s ~]# pstree -aps 18035
systemd,1 --switched-root --system --deserialize 22
`-sshd,2504 -D
`-sshd,16674
`-bash,16676
`-top,18035
總結
- 用戶 CPU 和 Nice CPU 高,說明用戶態進程占用了較多的 CPU,所以應該著重排查進程的性能問題。
- 系統 CPU 高,說明內核態占用了較多的 CPU,所以應該著重排查內核線程或者系統調用的性能問題。
- I/O 等待 CPU 高,說明等待 I/O 的時間比較長,所以應該著重排查系統存儲是不是出現了 I/O 問題。
- 軟中斷和硬中斷高,說明軟中斷或硬中斷的處理程式占用了較多的 CPU,所以應該著重排查內核中的中斷服務程式。
進程狀態
ps 或者 top ,可以查看進程的狀態,這些狀態包括運行(R)、空閑(I)、不可中斷睡眠(D)、可中斷睡眠(S)、僵屍(Z)以及暫停(T)等。
- 不可中斷狀態,表示進程正在跟硬體交互,為了保護進程數據和硬體的一致性,系統不允許其他進程或中斷打斷這個進程。進程長時間處於不可中斷狀態,通常表示系統有 I/O 性能問題。
- 僵屍進程表示進程已經退出,但它的父進程還沒有回收子進程占用的資源。短暫的僵屍狀態我們通常不必理會,但進程長時間處於僵屍狀態,就應該註意了,可能有應用程式沒有正常處理子進程的退出。
常見問題
CPU使用率很高,通過top等命令找不到相應的進程
- 應用里直接調用了其他二進位程式,這些程式通常運行時間比較短,通過 top 等工具也不容易發現。
- 應用本身在不停地崩潰重啟,而啟動過程的資源初始化,很可能會占用相當多的 CPU。
對於這類進程,我們可以用 pstree 或者 execsnoop 找到它們的父進程,再從父進程所在的應用入手,排查問題的根源。
學習筆記
來自極客時間:《Linux性能優化實戰》