淺談cpu.idle和cpu.load


1.概述

大家經常對一個系統的容量進行評估時,會參考cpu.idle和cpu.load指標,但是這兩個指標到底在什么區間,表示系統是正常或者異常呢,業內有不同的說法。因此本文搜集一些資料,並對一個系統進行壓測,最終來獲得一個比較客觀的觀點,如有不對,可以在評論區進行交流。

在開始之前,我們必須對系統運轉有一個整體的認識。在Linux內核中,每個進程都會被分配一個固定的時間片,默認為10ms,在這10ms中,該進程享有cpu的所有權。10ms看上去很短,但以2.6GHz的Intel處理器為例,10ms能夠處理5000w條指令,對於絕大多數的應用這已經足夠長了。如果該進程用完了10ms,或者有其他優先級高的進程發出請求,系統會觸發一個中斷,內核重新接管cpu,內核分配cpu給其他進程。10ms的分片讓用戶,也就是我們覺得我們的系統運轉非常流暢,盡管我們可能同時開了很多的應用。

2.cpu.idle

CPU利用率主要分為用戶態,系統態和空閑態,分別表示CPU處於用戶態執行的時間,系統內核執行的時間,和空閑系統進程執行的時間,三者之和就是CPU的總時間,當沒有用戶進程、系統進程等需要執行的時候,CPU就執行系統缺省的空閑進程。CPU的利用率就是指非空閑進程占用時間的比例,即CPU執行非空閑進程的時間 / CPU總的執行時間。

/proc文件系統是一個偽文件系統,它只存在內存當中,而不占用外存空間。它以文件系統的方式為內核與進程提供通信的接口。用戶和應用程序可以通過/proc得到系統的信息,並可以改變內核的某些參數。由於系統的信息,如進程,是動態改變的,所以用戶或應用程序讀取/proc目錄中的文件時,proc文件系統是動態從系統內核讀出所需信息並提交的。

cpu.idle是基於/proc/stat計算出來的,首先了解一下/proc/stat的各項指標的意義。

代碼塊
Shell
 
 
 
 
 
[xietao02@gh-trip-open-opengateway-staging01 ~]$ cat /proc/stat
cpu  30512019 2905 18888929 5215060855 449961 258 322293 482253 0
cpu0 12054132 723 5666598 1297356736 439476 258 173174 175261 0
cpu1 6256562 718 4332274 1305529992 4073 0 50163 105721 0
cpu2 6252205 723 4470475 1305772598 3466 0 49552 102278 0
cpu3 5949118 739 4419581 1306401527 2944 0 49403 98992 0
intr 10488180092 119 7 0 0 0 0 0 0 1 0 0 33 104 0 0 68 0 0 0 0 0 0 0 0 0 10319942 0 336 0 18155452 0 14 0 265289852 3907 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 18254375560
btime 1516246663
processes 13216259
procs_running 1
procs_blocked 0
softirq 3948723530 0 1488253637 8488 455883603 17 0 179 392363322 13619548 1598594736
 

第一行的數值表示的是CPU總的使用情況,cpu0、cpu1、cpu2、cpu3分別指每個cpu核心的cpu使用情況,下表解析第一行各數值的含義(單位:jiffies):

user (30512019)

從系統啟動開始累計到當前時刻,用戶態的CPU時間,不包含nice值為負進程。

nice (2905)

從系統啟動開始累計到當前時刻,nice值為負的進程所占用的CPU時間

system (18888929)

從系統啟動開始累計當前時刻,核心時間

idle (5215060855)

從系統啟動開始累計到當前時刻,除IO等待時間以外其它等待時間

iowait (449961)

從系統啟動開始累計到當前時刻,IO等待時間 2.5.41版本新增字段

irq (258)

從系統啟動開始累計到當前時刻,硬中斷時間 2.6.0版本新增字段

softirq (322293)

從系統啟動開始累計到當前時刻,軟中斷時間 2.6.0版本新增字段

stealstolen(482253)

當一台物理機有多個虛擬機時,該cpu在其他虛擬機運行的時間

which is the time spent in other operating systems when running in a virtualized environment 2.6.11

guest(0)

在cpu內核控制下,提供給在上面運行虛擬機占用的cpu時間

which is the time spent running a virtual  CPU  for  guest operating systems under the control of the Linux kernel 2.6.24

因為/proc/stat中的數值都是從系統啟動開始累計到當前時刻的積累值,所以需要在不同時間點t1和t2取值進行比較運算,當兩個時間點的間隔較短時,就可以把這個計算結果看作是CPU的即時利用率。

其他參數的含義

ctxt

上下文切換次數

 

btime

系統啟動到當前的時間

sec

process

自啟動以來,創建任務個數

 

procs_running

當前運行任務個數

 

procs_blocked

阻塞的任務個數

 

2.1 CPU的即時利用率的計算公式(top falcon命令顯示的):

CPU在t1到t2時間段總的使用時間 = ( user2+ nice2+ system2+ idle2+ iowait2+ irq2+ softirq2+stealstolen2+guest2) - ( user1+ nice1+ system1+ idle1+ iowait1+ irq1+ softirq1+stealstolen1+guest1)

CPU在t1到t2時間段空閑使用時間 = (idle2 - idle1)

CPU在t1到t2時間段即時利用率 =  1 - CPU空閑使用時間 / CPU總的使用時間

從top命令中看到的idle和falcon看到的cpu.idle都是以上的計算結果。

從falcon上看到的cpu.busy=1-cpu.idle。

2.2 CPU的平均利用率的計算公式(sar -u和ps aux命令顯示的)

1-(當前時間對應的cpu.idle值 )/ (當前時間對應的cpu.total值),cpu.total就是cpu那一行所有項的加和。

2.3 進程和線程的cpu使用率

/proc目錄中有一些以數字命名的目錄,它們是進程目錄。系統中當前運行的每一個進程在/proc下都對應一個以進程號為目錄名的目錄/proc/pid,它們是讀取進程信息的接口。此外,在Linux 2.6.0-test6以上的版本中/proc/pid目錄中有一個task目錄,/proc/pid/task目錄中也有一些以該進程所擁有的線程的線程號命名的目錄/proc/pid/task/tid,它們是讀取線程信息的接口。

linux中的輕量級進程(lwp)即為線程,對應tid。

計算某一個進程和某一個線程的cpu利用率,和計算系統的cpu利用率類似。讀取/proc/pid/stat或者讀取/proc/pid/task/stat中的參數來進行計算。

3. cpu.load(系統平均負載,通過top、uptime、和falcon可以查看)

系統平均負載被定義為在特定時間間隔內運行隊列中(在CPU上運行或者等待運行多少進程)的平均進程數。如果一個進程滿足以下條件則其就會位於運行隊列中:

  • 它沒有在等待I/O操作的結果

  • 它沒有主動進入等待狀態(也就是沒有調用’wait’)

  • 沒有被停止(例如:等待終止)

在Linux中,進程分為三種狀態,一種是阻塞的進程blocked process,一種是可運行的進程runnable process,另外就是正在運行的進程running process。

進程可運行狀態時,它處在一個運行隊列run queue中,與其他可運行進程爭奪CPU時間。 系統的load是指正在運行和准備好運行的進程的總數。比如現在系統有2個正在運行的進程,3個可運行進程,那么系統的load就是5。

cpu.load是基於/proc/loadavg進行統計的。
查看系統平均負載使用“cat /proc/loadavg”命令,輸出結果如下:
0.27 0.36 0.37 4/83 4828/
前三個指1、5、15分鍾內的平均進程數(可以簡單理解為每五秒統計一次,其實真實計算比較復雜。https://blog.csdn.net/jlds123/article/details/7617132)。后面兩個指(正在運行的進程數/進程總數)和最近運行的進程ID號。

另外,通過"load average"中的三個數字,我們還可以了解到當前服務器的負載的變化趨勢,如果1分鍾的CPU負載 > 5分鍾的CPU負載,說明服務器目前處在CPU負載高峰期;而如果1分鍾的CPU負載 < 5分鍾的CPU負載,則說明服務器的CPU負載高峰期剛剛過去了,如果是你處理了什么性能問題,則表明該處理已經顯現成效了。

cpu.load大於多少沒有性能夠問題呢?

理想情況下cpu不空閑,但每個線程又都能及時獲得cpu時間,沒有等待的線程,任務處理完,緊接着出現另外一個可運行線程來獲得cpu時間,此時cpu.load/cores=1。如果cpu.load過大則表示,有部分線程在等待獲得cpu資源,過小表示cpu資源比較空閑。

對於cpu.load多少開始出現性能問題,外界有不同的說法,有的認為cpu.load/cores最好不要超過1,有的認為cpu.load/cores最好不要超過3,有的認為cpu.load不超過2*cores-2即可。

針對技術商服務進行壓測時,發現load低時,接口TP999響應時間<50ms,而cpu.load/cores>4時,TP999響應時間約為200ms左右,多出來的時間可以理解為線程等待cpu處理的時間,可見cpu.load/cores過高時是影響接口響應時間的。

因此可以結合預期的接口響應時間,來定義每個服務的cpu.load/cores不超過多少。比如要求接口響應時間盡可能快的,最好確保cpu.load/cores不超過1,而對時間敏感性要求不太高時,一般要求cpu.load/cores不超過3。

 


免責聲明!

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



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