Linux系統下CPU使用(load average)梳理

散盡浮華發表於2017-04-05

 

在平時的運維工作中,當一臺伺服器的效能出現問題時,通常會去看當前的CPU使用情況,尤其是看下CPU的負載情況(load average)。對一般的系統來說,根據cpu數量去判斷。比如有2顆cup的機器。如果平均負載始終在1.2以下,那麼基本不會出現cpu不夠用的情況。也就是Load平均要小於Cpu的數量。

對於cpu負載的理解,首先需要搞清楚下面幾個問題:
 
1)系統load高不一定是效能有問題。
因為Load高也許是因為在進行cpu密集型的計算
 
2)系統Load高不一定是CPU能力問題或數量不夠。
因為Load高只是代表需要執行的佇列累計過多了。但佇列中的任務實際可能是耗Cpu的,也可能是耗i/0奶子其他因素的。
 
3)系統長期Load高,解決辦法不是一味地首先增加CPU
因為Load只是表象,不是實質。增加CPU個別情況下會臨時看到Load下降,但治標不治本。
 
4)在Load average 高的情況下需要鑑別系統瓶頸到底是CPU不足,還是io不夠快造成或是記憶體不足造成的。
 
===============================================================================================================
要想獲得伺服器的CPU負載情況,有下面幾種命令:
1)w命令
[root@localhost ~]# w
 12:12:41 up 167 days, 20:46,  2 users,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.1.5      10:01    1.00s  0.11s  0.00s w
root     pts/2    192.168.1.5      10:19    1:47m  0.04s  0.04s -bash
  
2)uptime命令(一般首先會根據最後那個15分鐘的load負載為準)
[root@localhost ~]# uptime
 12:12:55 up 167 days, 20:46,  2 users,  load average: 0.00, 0.01, 0.05
  
3)top命令
[root@localhost ~]# top
top - 12:13:22 up 167 days, 20:47,  2 users,  load average: 0.00, 0.01, 0.05
Tasks: 272 total,   1 running, 271 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.1 sy,  0.0 ni, 99.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 65759080 total, 58842616 free,   547908 used,  6368556 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used. 64264884 avail Mem
................
 
對上面第三行的解釋:
us(user cpu time):使用者態使用的cpu時間比。該值較高時,說明使用者程式消耗的 CPU 時間比較多,比如,如果該值長期超過 50%,則需要對程式演算法或程式碼等進行優化。
sy(system cpu time):系統態使用的cpu時間比。
ni(user nice cpu time):用做nice加權的程式分配的使用者態cpu時間比
id(idle cpu time):空閒的cpu時間比。如果該值持續為0,同時sy是us的兩倍,則通常說明系統則面臨著 CPU 資源的短缺。
wa(io wait cpu time):cpu等待磁碟寫入完成時間。該值較高時,說明IO等待比較嚴重,這可能磁碟大量作隨機訪問造成的,也可能是磁碟效能出現了瓶頸。
hi(hardware irq):硬中斷消耗時間
si(software irq):軟中斷消耗時間
st(steal time):虛擬機器偷取時間
 
以上解釋的這些引數的值加起來是100%。
 
4)vmstat
[root@localhost ~]# vmstat
procs -----------memory---------------------swap-------io---------system--------cpu-----
r  b      swpd   free    buff   cache    si   so    bi    bo     in   cs     us sy id wa st
3  0      0      1639792 724280 4854236  0    0     4     34     4    0      19 45 35  0  0
 
解釋說明:
-----------------------------
procs部分的解釋
r 列表示執行和等待cpu時間片的程式數,如果長期大於1,說明cpu不足,需要增加cpu。
b 列表示在等待資源的程式數,比如正在等待I/O、或者記憶體交換等。
-----------------------------
cpu部分的解釋
us 列顯示了使用者方式下所花費 CPU 時間的百分比。us的值比較高時,說明使用者程式消耗的cpu時間多,但是如果長期大於50%,需要考慮優化使用者的程式。
sy 列顯示了核心程式所花費的cpu時間的百分比。這裡us + sy的參考值為80%,如果us+sy 大於 80%說明可能存在CPU不足。
wa 列顯示了IO等待所佔用的CPU時間的百分比。這裡wa的參考值為30%,如果wa超過30%,說明IO等待嚴重,這可能是磁碟大量隨機訪問造成的,也可能磁碟或者
   磁碟訪問控制器的頻寬瓶頸造成的(主要是塊操作)。
id 列顯示了cpu處在空閒狀態的時間百分比
-----------------------------
system部分的解釋
in 列表示在某一時間間隔中觀測到的每秒裝置中斷數。
cs列表示每秒產生的上下文切換次數,如當 cs 比磁碟 I/O 和網路資訊包速率高得多,都應進行進一步調查。
-----------------------------
memory部分的解釋
swpd 切換到記憶體交換區的記憶體數量(k表示)。如果swpd的值不為0,或者比較大,比如超過了100m,只要si、so的值長期為0,系統效能還是正常
free 當前的空閒頁面列表中記憶體數量(k表示)
buff 作為buffer cache的記憶體數量,一般對塊裝置的讀寫才需要緩衝。
cache: 作為page cache的記憶體數量,一般作為檔案系統的cache,如果cache較大,說明用到cache的檔案較多,如果此時IO中bi比較小,說明檔案系統效率比較好。
-----------------------------
swap部分的解釋
si 由記憶體進入記憶體交換區數量。
so由記憶體交換區進入記憶體數量。
-----------------------------
IO部分的解釋
bi 從塊裝置讀入資料的總量(讀磁碟)(每秒kb)。
bo 塊裝置寫入資料的總量(寫磁碟)(每秒kb)
 
 
5)也可以使用dstat命令檢視cpu資訊
[root@localhost ~]# dstat
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
 19  45  35   0   0   0|  30k  265k|   0     0 |   0     0 |9025    12k
  9  18  73   0   0   0|   0   144k|2578k   65k|   0     0 |3956  4343
 
6)可以使用iostat檢視IO負載
[root@localhost ~]# iostat 1 1
Linux 2.6.32-696.16.1.el6.x86_64 (nc-ftp01.kevin.cn)    2017年12月29日     _x86_64_    (4 CPU)
 
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          19.32    0.00   45.44    0.06    0.26   34.93
 
Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
xvda             14.17        29.94       265.17   63120486  558975100

解釋說明:
avg-cpu: 總體cpu使用情況統計資訊,對於多核cpu,這裡為所有cpu的平均值
%user: 在使用者級別執行所使用的CPU的百分比.
%nice: nice操作所使用的CPU的百分比.
%sys: 在系統級別(kernel)執行所使用CPU的百分比.
%iowait: CPU等待硬體I/O時,所佔用CPU百分比.
%idle: CPU空閒時間的百分比.

Device段:各磁碟裝置的IO統計資訊
tps: 每秒鐘傳送到的I/O請求數.
Blk_read /s: 每秒讀取的block數.
Blk_wrtn/s: 每秒寫入的block數.
Blk_read:   讀入的block總數.
Blk_wrtn:  寫入的block總數.

[root@localhost ~]# iostat -x -k -d 1
Linux 2.6.32-696.el6.x86_64 (centos6-vm02)  01/04/2018  _x86_64_    (4 CPU)

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
scd0              0.00     0.00    0.00    0.00     0.00     0.00     8.00     0.00    0.36    0.36    0.00   0.36   0.00
vda               0.01     0.13    0.04    0.13     0.60     0.89    18.12     0.00    2.78    0.19    3.53   2.55   0.04
dm-0              0.00     0.00    0.04    0.22     0.58     0.88    11.25     0.00    3.27    0.25    3.82   1.61   0.04
dm-1              0.00     0.00    0.00    0.00     0.00     0.00     8.00     0.00    0.13    0.13    0.00   0.04   0.00
dm-2              0.00     0.00    0.00    0.00     0.00     0.00     7.91     0.00    0.19    0.10    5.00   0.16   0.00

解釋說明:
rrqm/s: 每秒對該裝置的讀請求被合併次數,檔案系統會對讀取同塊(block)的請求進行合併
wrqm/s: 每秒對該裝置的寫請求被合併次數
r/s: 每秒完成的讀次數
w/s: 每秒完成的寫次數
rkB/s: 每秒讀資料量(kB為單位)
wkB/s: 每秒寫資料量(kB為單位)
avgrq-sz:平均每次IO操作的資料量(扇區數為單位)
avgqu-sz: 平均等待處理的IO請求佇列長度
await: 平均每次IO請求等待時間(包括等待時間和處理時間,毫秒為單位)
svctm: 平均每次IO請求的處理時間(毫秒為單位)
%util: 採用週期內用於IO操作的時間比率,即IO佇列非空的時間比率

如果 %util 接近 100%,說明產生的I/O請求太多,I/O系統已經滿負荷,該磁碟可能存在瓶頸。
idle小於70% IO壓力就較大了,一般讀取速度有較多的wait。
同時可以結合vmstat 檢視檢視b引數(等待資源的程式數)和wa引數(IO等待所佔用的CPU時間的百分比,高過30%時IO壓力高)

簡單說下CPU負載和CPU利用率的區別

0)load average:系統平均負載是CPU的Load,它所包含的資訊不是CPU的使用率狀況,而是在一段時間內CPU正在處理以及等待CPU處理的程式數之和的統計資訊,
   也就是CPU使用佇列的長度的統計資訊,這個數字越小越好。

1)CPU使用率:顯示的是程式在執行期間實時佔用的CPU百分比。

2)CPU負載:顯示的是一段時間內正在使用和等待使用CPU的平均任務數。CPU使用率高,並不意味著負載就一定大。
舉例來說:如果我有一個程式它需要一直使用CPU的運算功能,那麼此時CPU的使用率可能達到100%,但是CPU的工作負載則是趨近於"1",因為CPU僅負責一個工作啊。
如果同時執行這樣的程式兩個呢?CPU的使用率還是100%,但是工作負載則變成2了。所以也就是說,當CPU的工作負載越大,代表CPU必須要在不同的工作之間進行頻繁
的工作切換。

 
3)CPU利用率高,並不意味著負載就一定大。
舉例來說:
如果有一個程式它需要一直使用CPU的運算功能,那麼此時CPU的使用率可能達到100%,但是CPU的工作負載則是趨近於"1",因為CPU僅負責一個工作!
如果同時執行這樣的程式兩個呢?CPU的使用率還是100%,但是工作負載則變成2了。所以也就是說,當CPU的工作負載越大,代表CPU必須要在不同的工作之間
進行頻繁的工作切換。
  
------------------------下面通過一個電話亭打電話的比喻來說明這兩者之間的區別------------------------
某公用電話亭,有一個人在打電話,四個人在等待,每人限定使用電話一分鐘,若有人一分鐘之內沒有打完電話,只能掛掉電話去排隊,等待下一輪。
電話在這裡就相當於CPU,而正在或等待打電話的人就相當於任務數。
  
在電話亭使用過程中,肯定會有人打完電話走掉,有人沒有打完電話而選擇重新排隊,更會有新增的人在這兒排隊,這個人數的變化就相當於任務數的增減。
為了統計平均負載情況,我們5分鐘統計一次人數,並在第1、5、15分鐘的時候對統計情況取平均值,從而形成第1、5、15分鐘的平均負載。
  
有的人拿起電話就打,一直打完1分鐘,而有的人可能前三十秒在找電話號碼,或者在猶豫要不要打,後三十秒才真正在打電話。如果把電話看作CPU,人數看
作任務,我們就說前一個人(任務)的CPU利用率高,後一個人(任務)的CPU利用率低。當然, CPU並不會在前三十秒工作,後三十秒歇著,只是說,有的程
序涉及到大量的計算,所以CPU利用率就高,而有的程式牽涉到計算的部分很少,CPU利用率自然就低。但無論CPU的利用率是高是低,跟後面有多少任務在排隊
沒有必然關係。

=========正確理解%iowait和CPU使用率=========

1)%steal
一般是在虛擬機器中才能看到數值,比如CPU overcommitment很嚴重的VPS,而%guest和%nice一般都很低,所以也可以
根據/proc/stat或者top可得,user + nice + system + idle + iowait + irq + softirq + steal = 100

2)Linux程式狀態
執行狀態(TASK_RUNNING):
  是執行態和就緒態的合併,表示程式正在執行或準備執行,Linux 中使用TASK_RUNNING 巨集表示此狀態
可中斷睡眠狀態(淺度睡眠)(TASK_INTERRUPTIBLE):
  程式正在睡眠(被阻塞),等待資源到來是喚醒,也可以通過其他程式訊號或時鐘中斷喚醒,進入執行佇列。Linux 使用TASK_INTERRUPTIBLE 巨集表示此狀態。
不可中斷睡眠狀態(深度睡眠狀態)(TASK_UNINTERRUPTIBLE):
  其和淺度睡眠基本類似,但有一點就是不可被其他程式訊號或時鐘中斷喚醒。Linux 使用TASK_UNINTERRUPTIBLE 巨集表示此狀態。
暫停狀態(TASK_STOPPED):
  程式暫停執行接受某種處理。如正在接受除錯的程式處於這種狀態,Linux 使用TASK_STOPPED 巨集表示此狀態。
僵死狀態(TASK_ZOMBIE):
  程式已經結束但未釋放PCB,Linux 使用TASK_ZOMBIE 巨集表示此狀態。

3)%iowait 的正確認知
%iowait 表示在一個取樣週期內有百分之幾的時間屬於以下情況:CPU空閒、並且有仍未完成的I/O請求。

對 %iowait 常見的誤解有兩個:
  一是誤以為 %iowait 表示CPU不能工作的時間,
  二是誤以為 %iowait 表示I/O有瓶頸。

首先 %iowait 升高並不能證明等待I/O的程式數量增多了,也不能證明等待I/O的總時間增加了。
例如:
在CPU繁忙期間發生的I/O,無論IO是多還是少,%iowait都不會變;
當CPU繁忙程度下降時,有一部分IO落入CPU空閒時間段內,導致%iowait升高。
再比如:IO的併發度低,%iowait就高;IO的併發度高,%iowait可能就比較低。

可見%iowait是一個非常模糊的指標,如果看到 %iowait 升高,還需檢查I/O量有沒有明顯增加,
avserv/avwait/avque等指標有沒有明顯增大,應用有沒有感覺變慢,如果都沒有,就沒什麼好擔心的。

4)檢視CPU使用率,推薦如下Linux命令:
# top
# sar -u 1 5
# vmstat -n 1 5
# mpstat -P ALL 1 5

檢視Load的值,推薦如下Linux命令:
# top
# uptime
# sar -q 1 5

load average相關梳理(一分鐘,五分鐘,十五分鐘的平均CPU負載,最重要的指標是最後一個數字,即前15分鐘的平均CPU負載,這個數字越小越好。所謂CPU負載指的是一段時間內任務佇列的長度,通俗的講,就是一段時間內一共有多少任務在使用或等待使用CPU。(當前的"負載值除以cpu核數"就是cpu的利用率))

load average表示的是系統的平均負荷,即CPU的Load。
它所包含的資訊不是CPU的使用率狀況,而是在一段時間內CPU正在處理以及等待CPU處理的程式數之和的統計資訊,也就是CPU使用佇列的長度的統計資訊。
它包括3個數字,分別表示系統在1、5、15分鐘內程式佇列中的平均程式數量(即處理的程式情況),
原則上來說這3個數字越小越好,數字越小表示伺服器的工作量越小,系統負荷比較輕
 
當CPU完全空閒的時候,平均負荷為0(即load average的值為0);當CPU工作量飽和的時候,平均負荷為1。
 
這裡需要注意的是:
load average這個輸出值,這三個值的大小一般不能大於系統邏輯CPU的個數
比如一臺伺服器有4個邏輯CPU,如果load average的三個值長期大於4時,說明CPU很繁忙,負載很高,可能會影響系統效能;
但是偶爾大於4時,倒不用擔心,一般不會影響系統效能。
相反,如果load average的輸出值小於CPU的個數,則表示CPU還有空閒,比如本例中的輸出,CPU是比較空閒的。
 
 
-------------load average舉例理解---------------
判斷系統負荷是否過重,必須理解load average的真正含義。假設當前我的一臺伺服器只有一個CPU,所有的運算都必須由這個CPU來完成。
不妨把這個CPU想象成一座大橋,橋上只有一根車道,所有車輛都必須從這根車道上通過(很顯然,這座橋只能單向通行)。
1)系統負荷為0,意味著大橋上一輛車也沒有。
2)系統負荷為0.5,意味著大橋一半的路段有車。
3)系統負荷為1.0,意味著大橋的所有路段都有車,也就是說大橋已經"滿"了。但是必須注意的是,直到此時大橋還是能順暢通行的。
4)系統負荷為1.7,意味著車輛太多了,大橋已經被佔滿了(100%),後面等著上橋的車輛為橋面車輛的70%。
   以此類推,系統負荷2.0,意味著等待上橋的車輛與橋面的車輛一樣多;
   系統負荷3.0,意味著等待上橋的車輛是橋面車輛的2倍。
   總之,當系統負荷大於1,後面的車輛就必須等待了;系統負荷越大,過橋就必須等得越久。
 
CPU的系統負荷,基本上等同於上面的類比。大橋的通行能力,就是CPU的最大工作量;橋樑上的車輛,就是一個個等待CPU處理的程式(process)。
如果CPU每分鐘最多處理100個程式,那麼:
系統負荷0.2,意味著CPU在這1分鐘裡只處理20個程式;
系統負荷1.0,意味著CPU在這1分鐘 里正好處理100個程式;
系統負荷1.7,意味著除了CPU正在處理的100個程式以外,還有70個程式正排隊等著CPU處理。
 
為了伺服器順暢執行,系統負荷最好不要超過1.0,這樣就沒有程式需要等待了,所有程式都能第一時間得到處理。
很顯然,1.0是一個關鍵值,超過這個值,系統就不在最佳狀態了,就需要動手干預了。
 
 
--------1.0是系統負荷的理想值嗎?-----------
不一定,系統管理員往往會留一點餘地,當這個值達到0.7,就應當引起注意了。
以往經驗是這樣的:
當系統負荷持續大於0.7,必須開始調查了,問題出在哪裡,防止情況惡化。
當系統負荷持續大於1.0,必須動手尋找解決辦法,把這個值降下來。
當系統負荷達到5.0,就表明系統有很嚴重的問題,長時間沒有響應,或者接近當機了。覺不能讓系統達到這個值。
 
 
上面,假設我的這臺伺服器只有1個CPU。如果它裝了2個CPU,就意味著伺服器的處理能力翻了一倍,能夠同時處理的程式數量也翻了一倍。
還是用大橋來類比,兩個CPU就意味著大橋有兩根車道了,通車能力翻倍了。
所以,2個CPU表明系統負荷可以達到2.0,此時每個CPU都達到100%的工作量。推廣開來,n個CPU的伺服器,可接受的系統負荷最大為n.0。
 
 
---------至於load average是多少才算理想,這個有爭議,各有各的說法---------
個人比較贊同CPU負載小於等於"核心數乘以0.5-0.7"算是一種理想狀態。
比如4核CPU的伺服器,理想負載是小於等於2,最好不要超過2.8,否則效能多少會受影響。
 
不管某個CPU的效能有多好,1秒鐘能處理多少任務,可以認為它無關緊要,雖然事實並非如此。
在評估CPU負載時,只以5分鐘為單位做統計任務佇列長度。如果每隔5分鐘統計的時候,發現任務佇列長度都是1,那麼CPU負載就為1。
 
假如現在某臺伺服器只有一個單核的CPU,負載一直為1,意味著沒有任務在排隊,還不錯。
但是這臺伺服器是雙核CPU,等於是有4個核心,每個核心的負載為1的話,總負載為4。這就是說,如果這臺伺服器的CPU負載長期保持在4左右,還可以接受。
但是每個核心的負載為1,並不能算是一種理想狀態!這意味著伺服器的CPU一直很忙,不得清閒。
 
 
-----------load average返回三個平均值應該參考哪個值?------------
如果只有1分鐘的系統負荷大於1.0,其他兩個時間段都小於1.0,這表明只是暫時現象,問題不大。
如果15分鐘內,平均系統負荷大於1.0(調整CPU核心數之後),表明問題持續存在,不是暫時現象。
所以應該主要觀察"15分鐘系統負荷",將它作為伺服器正常執行的指標。
 
----------如何來降低伺服器的CPU負載?--------------
最簡單辦法的是更換效能更好的伺服器,不要想著僅僅提高CPU的效能,那沒有用,CPU要發揮出它最好的效能還需要其它軟硬體的配合。
在伺服器其它方面配置合理的情況下,CPU數量和CPU核心數(即核心數)都會影響到CPU負載,因為任務最終是要分配到CPU核心去處理的。兩塊CPU要比一塊
CPU好,雙核要比單核好。因此,需要記住的是:除去CPU效能上的差異,CPU負載是基於核心數來計算的。有一個說法是"有多少核心,即有多少負載"。

相關文章