一. 上節回顧
1. CPU上下文切換:CPU寄存器和程序計數器
2. CPU上下文可以分為幾個不同的場景:進程上下文切換,線程上下文切換,中斷上下文切換
3. 線程是調度的基本單位,進程是資源擁有的基本單位
二. 自願上下文切換和非自願上下文切換
vmstat:只給出了系統總體的上下文切換情況,要想查看每個進程的詳細情況,需要pidstat
pidstat -w 5 #每隔5s輸出1組數據(重點關注)
cswch/s:表示每秒自願上下文切換的次數
nvcswch/s:表示每秒非自願上下文切換的次數
1. 自願上下文切換
自願上下文切換是指進程無法獲取所需自願,導致的上下文切換,比如:I/O,內存等系統資源不足時,就會發生自願上下文切換
2. 非自願上下文切換
非自願上下文切換是指進程由於時間片已到等原因,被系統強制調度
3. 案例分析
sysbench是一個多線程的基准測試工具,一般來評估不同系統參數下的數據庫負載情況
(1) 安裝
a. yum安裝
yum install -y sysbench #不需要提前准備包
b. tar.gz包安裝
#解壓: tar -zxvf 文件名.tar.gz #進入到解壓之后的目錄 cd 文件名 ./configure #編譯安裝 make&&make install
(2) 案例操作和分析步驟
a. 在第一個終端里運行sysbench,模擬系統多線程調用的瓶頸
#以10個線程運行5分鍾的基准測試,模擬多線程切換的問題 sysbench --threads=10 --max-time=300 threads run
b. 在第二個終端運行vmstat,觀察上下文切換情況
vmstat 3
發現:cs列的上下文切換次數從24一下子到100多萬,同時觀察其他幾個指標
r列:就緒隊列的長度已經超過5個,超過了系統CPU的個數4,有大量CPU競爭
us(user)和sy(system)列:這兩列的CPU使用率加起來上升到80%以上,其中系統CPU使用率,也就是sy列高達71%,說明CPU主要是被內核占用了
in列:中斷次數上升到了4萬多,說明中斷處理也是一個潛在的問題
綜合這幾個指標,可以知道,系統的就緒隊列過長,也就是正在運行和等待CPU的進程數過多,導致了大量的上下文切換,而上下文切換又導致了系統CPU的占用率升高
那么到底是什么進程導致了這些問題?
c. 在第三個終端用pidstat來看一下,CPU和進程上下文切換情況
pidstat -w -u 1 # -w參數,表示輸出進程切換指標,-u參數,表示輸出CPU使用指標
從pidstat的輸出可以發現,CPU的升高果然是sysbench導致的,它的CPU使用率已經達到300%多,但是發現輸出的上下文切換次數很小,比vmstat看到的100多萬明顯小了太多了,這是怎么回事?
我們再來回想一下,前面提到的幾種上下文切換場景,其中一點提到,Linux調度的基本單位實際上是線程,而我們的場景sysbench模擬的也是線程調度問題,那么是不是pidstat忽略了線程的數據?
pidstat:默認是顯示進程的指標數據,加上 -t 參數,才會輸出線程的指標
pidstat -wt 1 # -wt 表示輸出線程的上下文切換指標
可以看到,雖然sysbench進程(也就是主線程)的上下文切換次數看起來並不多,但它的子線程的上下文切換卻很多,看來,上下文切換的根源,還是過多的sysbench線程
三. CPU使用率
CPU使用率:load average:0.00,0.56,1.60
在性能測試中常用什么指標來描述系統的CPU性能?
估計很多人,可能不是平均負載,也不是CPU上下文切換,而是另一個更直觀的指標:CPU使用率
CPU使用率:是單位時間內CPU使用情況的統計,以百分比的形式展示,那CPU使用率是怎么算出來的?
為了維護CPU時間,Linux通過事先定義的節拍率(表示為HZ),觸發時間中斷,並使用全局變量記錄了開機以來的節拍數,每發送一次時間中斷,全部變量的值加1
節拍率HZ是內核的可配置選項,可以設置100,250,1000等,不同的系統可能設置不同數值,可以通過下面命令查看:
grep 'CONFIG_HZ=' /boot/config-$(uname -r)
同時,正因為節拍率HZ是內核選項,所以用戶空間程序並不能直接訪問,為了方便用戶空間程序,內核還提供了一個用戶空間節拍率USER_HZ,它總是固定為100,也就是1/100秒,這樣用戶空間程序並不需要關心內核中HZ被設置了多少?因為它看到的總是固定值USER_HZ
Linux通過/proc虛擬文件系統,向用戶空間提供了系統內部狀態的信息,而/proc/stat提供的就是系統的CPU和任務統計信息,比如說,如果你只關心CPU的話,可以執行下面的命令:
cat /proc/stat | grep ^cp
這里輸出的一個表格,其中,第一列表示的是CPU編號,如CPU,CPU0,CPU1,而第一行沒有編號為2的CPU,表示的是所有CPU的累加,其他列則表示不同場景下CPU的累加節拍數,它的單位是USER_HZ,也就是10ms(1/100秒),這其實就是不同場景下的CPU時間
(1) 怎么查看CPU使用率
top
top:顯示了系統總體的CPU和內存使用情況,以及各個進程的資源使用情況,默認是3s刷新一次
可以發現,top並沒有細分進程的用戶態CPU和內核態CPU,那要怎么查看每個進程的詳細情況呢?是不是上一次用到的pidstat命令,它可以專門分析每個進程的CPU使用情況
pidstat 1 5 # 每隔1s輸出一組數據,共輸出5組
pidstat命令,CPU使用率如下:
%usr:用戶態CPU使用率
%system:內核態CPU使用率
%guest:運行虛擬機CPU使用率
%wait:等待CPU使用率
%cpu:總的CPU使用率
最后Average部分,還計算了5組數據平均值
通過top,ps,pidstat等工具,能夠很快找到CPU使用率過高(100%)的進程,接下來,可能又想知道,占用CPU高的進程的代碼是哪個函數?或者哪個類里面的方法,只有這樣,我們才能更快的,有針對性的進程優化