概述
做壓力測試的時候,我們經常會關注兩個指標,CPU利用率和CPU負載
Linux中,進程分為三種狀態:
-
阻塞的進程blocked process
-
可運行的進程runnable process
-
正在運行的進程running process
當進程處於不可中斷時,進程會等待I/O設備的數據或者系統調用;進程處於可運行狀態時,它處在一個運行隊列中,與其他可運行進程爭奪CPU
CPU使用率
CPU使用率指的是程序在運行期間實時占用的CPU百分比,這是對一個時間段內CPU使用狀況的統計。
通過這個指標可以看出在某一個時間段內CPU被占用的情況
load-average
它指的是正在運行(running)和不可中斷(等待IO)的平均進程數。在linux top命令中指的是是最近1分鍾、5分鍾和15分鍾的系統平均負載
cpu負載的計算
CPU數量和CPU內核數都會影響到CPU負載,因為任務最終是要分配到CPU核心去處理的。
兩塊CPU要比一塊CPU好,雙核要比單核好。因此,除去CPU性能上的差異,CPU負載是基於內核數來計算的。
“有多少內核,就有多少load”。如單核負載為1.00,雙核負載為2.00.以此類推。
舉例說明cpu負載
大家都要坐電梯坐電梯。假設一部電梯能站10個人,那當1-10人坐電梯時,可以認為電梯的load<1;
正好10人時,load=1;
超過10人時,load>1;
如果有15個人要坐電梯,那就是說能有10人直接上過山車,另外5人需要等待。
此時電梯的load=15/10 = 1.5
也就是說,1.5的負載表示系統當前滿負荷運轉,且還有相當於50%滿負荷的請求在等待
對於load average的臨界值,業內有兩種判斷依據
load average <= cpu核數 * 0.7
load average <= cpu核數 - 1
為什么會有高Load,低CPU使用率的情況?
依然拿電梯的例子來說明。假設一共有20個人來坐電梯。電梯一次運行5分鍾。兩次運行之間,第一批10人下來,第二批10人來,電梯等人進來,加上關門時間時間也要3分鍾。這種情況下電梯的使用率就是50%左右。而過山車的load是2。對應到我們的CPU上,當運行的進程(線程)過多時,頻繁的上下文切換耗費了大量的CPU時間,導致真正用在運算的CPU時間片比較少(低CPU使用率),卻有很多進程在等待運行(高Load)。
Cpu 利用率和 load 值高低沒有直必然關系
我們做壓測的時候一般認為 CPU 利用率和 Load 值是正比的關系,既Load 值越高,CPU 利用率就越高。但是事實上有時候 Load 很高,CPU 利用率卻比較低(多核更可能出現分配不均的情況)。
因為 Load 是等待處理的任務隊列,當你的應用在等待同步消息返回處理的同時,CPU 還是會將時間切片分配給這些線程。
而真正需要 CPU 的那些線程,卻不得不在得不到時間片以后暫時放棄工作被掛起。
CPU利用率高也並不意味着負載就一定大,可能這個任務是一個CPU密集型的。CPU低利用率的情況下也會有高Load Average的情況。當CPU分配時間片以后,是否使用完全取決於使用者,因此完全可能出現低利用率高Load Average的情況。
因此在程序設計的時候要考慮如何利用好CPU的這個資源,如何均勻的將壓力分攤到各個CPU 上(有時候一個線程在不斷循環,導致單個CPU負荷很高)
再舉例
公共電話亭里有一個人在打電話,后面有四個人在等待,每人限定使用電話一分鍾。若有人一分鍾之內沒有打完電話,只能掛掉電話去排隊,等待下一輪。公共電話在就相當於CPU,而正在打電話或等待打電話的人就相當於任務數。
在電話亭使用過程中,肯定會有人打完電話走掉,有人沒有打完電話而選擇重新排隊,更會有新增的人在這兒排隊。人數的變化就相當於任務數的增減。為了統計平均負載情況,我們5秒鍾統計一次人數,並在第1、5、15分鍾的時候對統計情況取平均值,從而形成第1、5、15分鍾的平均負載。
有的人拿起電話就打,打滿1分鍾,有的人可能前三十秒在找號碼,或者猶豫要不要打,后三十秒才真正開始打。如果把電話看作CPU,人數看作任務,我們可以說前一個人(任務)的CPU利用率高,后一個人(任務)的CPU利用率低。當然, CPU並不會在前三十秒工作,后三十秒歇着,它一直在處於load狀態。
有的程序涉及到大量的計算,所以CPU利用率就高,而有的程序牽涉到計算的部分很少,CPU利用率自然就低。但無論CPU的利用率是高是低,跟后面有多少任務在排隊沒有必然關系(cpu利用率和load沒有必然關系)。
在Linux系統中,可以通過命令看到系統平均負載load-average的輸出
uptime
top
saq -q
runq-sz:運行隊列的長度(等待運行的進程數)
plist-sz:進程列表中進程(processes)和線程(threads)的數量
ldavg-1:最后1分鍾的系統平均負載(Systemload average)
ldavg-5:過去5分鍾的系統平均負載
ldavg-15:過去15分鍾的系統平均負載