簡介
本文主要從常用的top命令入手,說明linux下的cpu 負載是怎么回事,以及幫助大家簡單判斷cpu負載高的原因。
[poc]
top查看機器負載
我們在linux下使用top指令將會輸出如下圖所示頁面:
這里的load average以及縮寫的us、sy、ni、id、wa、hi、si、st都是些什么意思呢?這些值在一個什么樣的區間比較合理呢?如果值超過了合理區間,應該怎么處理呢?這篇將來聊聊這些問題。
load average
load average代表CPU的平均負載值,上面示例中的load average: 0.00, 0.03, 0.00分別表示當前CPU在1分鍾、5分鍾和15分鍾內的平均負載。
這些負載值是怎么來的呢?
這些數據來自於文件/proc/loadavg,內核會負責統計出這些數據。
top和uptime命令顯示的內容就來自於這個文件,根據proc的幫助文件可知,這里的值就是單位時間內處於運行狀態以及等待磁盤 I/O狀態的平均job數量。這里的運行狀態和job都是內核的概念,這里進行說明:
1、 對於內核而言,進程和線程都是job
2、 job處於運行狀態指job處於內核的運行隊列中,正在或等待被CPU調度(用戶空間的進程正在運行不代表需要被CPU調度,有可能在等待I/O,也有可能在sleep等等)
因為某一刻(瞬間)等待調度的進程多少並不能反映系統的整體壓力,所以這里取了1,5和15分鍾的平均值。
那么這個值的大小反映系統什么樣的一個壓力狀態呢?這里以單核CPU為例
1、 小於1: 說明平均每次只有不到一個job在忙,對於單核的CPU來說,完全能處理過來
2、 等於1: 說明平均每次剛好有一個job在忙,對於單核的CPU來說,剛好能處理過來
3、 大於1: 說明平均每次有多於一個job在忙,對於單核的CPU來說,由於一次只能處理一個任務,所以肯定有任務在等待,說明系統負載較大,調度不過來,有job需要等待
對於單核cpu,一旦大於1,就說明job得不到及時調度,系統性能將會受到影響。對於2核心來說,該值大於2才說明cpu忙不過來。
那這個值多大比較合適呢?其實沒有一個標准值,但一般的做法是預留一定的空間來應對系統負載的波動,建議控制在“0.7核數”以內,比如4核,那么0.74=2.8比較合適,一旦超過這個值,需要分析原因並着手解決。
top之%Cpu(s)
load average通過統計等待運行的平均job數量來推斷CPU的繁忙程度,而%Cpu(s)則直接統計CPU處於不同狀態的時間,比上面的load average更直觀,所以在實際上也被使用的更多。
總體來說,CPU會處於下面三種狀態中的一種:
1、 Idle: 處於空閑狀態,沒有任務需要調度
2、 User space: 正在運行user space的代碼(處於用戶態)
3、 Kernel: 正在運行內核的代碼(處於內核態)
對上面這三種狀態,內核又進一步細分為很多狀態,這里以上面輸出的8種狀態為例進行說明:
1、 2.5 us : 表示CPU有2.5%的時間在運行用戶態代碼(即在運行用戶態程序)
2、 1.8 sy : 表示CPU有1.8%的時間在運行內核態代碼。內核負責管理系統的所有進程和硬件資源,所有的內核代碼都運行在內核態,當用戶態進程需要訪問硬件資源時,如分配內存,讀寫I/O等,也需要通過系統調用進入內核態運行內核代碼。%sy高說明內核占用太多資源,或者用戶進程發起了太多的系統調用。
3、 3.1 ni : 表示CPU有3.1%的時間在運行niceness不為0的進程代碼。默認情況下,進程的niceness值都為0,但可以通過命令nice來啟動一個進程並指定其niceness值,niceness的取值范圍是-20到19,值越小,表示優先級越高,越優先被內核調度。
4、 90.5 id : 表示CPU有90.5%的時間處於空閑狀態
5、 1.7 wa : 表示CPU有1.7%的時間處於I/O等待狀態。通常情況下,當CPU遇到一個I/O操作時,會先觸發I/O操作,然后去干別的,等I/O操作完成后,CPU再接着繼續工作,但如果這時系統比較空閑,CPU沒有別的事情可以做,那么CPU將處於等待狀態,這種處於等待狀態的時間將會被統計進I/O wait,也就是說CPU處於I/O wait狀態即CPU閑着沒事干在等I/O操作結束,和idle幾乎是一樣的。這個值高說明CPU閑且I/O操作多或者I/O操作慢,但低並不能說明沒有I/O操作或者I/O操作快,有可能是CPU在忙別的,所以這只是一個參考值,需要和其他的統計項一起來分析。
6、 0.0 hi & 0.4 si : 這兩個值反映了CPU有多少時間花在了中斷處理上,hi(hardware interrupts)是硬件中斷,si(softirqs)是軟件中斷。硬件中斷一般由I/O設備引起,如網卡、磁盤等,發生硬件中斷后,CPU需要立即處理,當硬件中斷中需要處理的事情很多時,內核會生成相應的軟中斷,然后將耗時且不需要立即處理完成的操作放在軟中斷中執行,比如當網卡收到網絡包時,需要CPU立即把數據拷貝到內存中去,因為網卡自帶的緩存較小,如果不及時處理的話后面的數據包就進不來,導致丟包,當數據拷貝到內存中之后,就不需要那么着急的處理了,這時候可以將處理數據包(協議棧)的代碼放在軟中斷中執行。本人不是內核專家,關於軟中斷的部分請參考Understanding the Linux Kernel, 3rd Edition
7、 0.0 st : %st和虛擬機有關,當系統運行在虛擬機中時,當前虛擬機就會和宿主機以及其它的虛擬機共享CPU,%st就表示當前虛擬機在等待CPU為它服務的時間。該值越大,表示物理CPU被宿主機和其它虛擬機占用的時間越長,導致當前虛擬機得不到充足的CPU資源。如果%st長時間大於0,說明CPU資源得不到滿足,這時可以考慮將虛擬機移到其它機器上,或者減少當前機器運行的虛擬機數量。
上面這些統計項的總和等於100%,除了%idle之外,其它的任何一項數值過高都代表系統有問題,下面進行問題解決。
負載過高問題處理
1、 %us過高 : 表示有用戶態進程占用了過多的CPU,通過top命令可以很清楚的看到是哪個進程,如果這不是預期的行為,可以通過kill命令殺死相應的進程或者重啟它
2、 %sy過高 : 如果只是偶爾過高的話,不用擔心,但如果是持續走高的話,就需要重視,有可能是某些進程的系統調用太頻繁,比如進程不停的往控制台輸出日志,但如果用戶態的進程都沒有問題,那可能是內核里面的代碼出現了問題,尤其是代碼寫的不好的驅動模塊
3、 %ni過高 : 說明有人用nice程序運行了比較耗CPU的進程。如果niceness值大於0的話,就沒什么好擔心的,因為它的優先級比默認優先級要低,不會影響CPU性能,但最好還是確認一下該進程不會搶占系統的其它資源,如內存、磁盤I/O等,避免對系統整體性能造成影響。如果niceness值小於0的話,表示該進程優先級高且占用CPU資源多,需要確保該進程占用的CPU資源是符合預期的,如果不是,可以用top命令把它找出來並kill掉或者重啟。
4、 %wa過高 : 意味着系統中有進程在做大量的I/O操作,或者在讀寫速度比較慢的I/O設備,比如頻繁的讀寫磁盤,這時可以通過iotop命令來查看是哪些進程占I/O,然后再針對不同的進程做相應的處理;還有一種情況就是系統在頻繁的使用交換分區,這時需要解決的就是內存的問題,而不是I/O的問題。
5、 %hi或者%si過高 : %hi過高一般是硬件出問題了,%si過高一般是內核里面的代碼出問題了
6、 %st 過高 : 正如上面介紹介紹的那樣,%st過高表示當前虛擬機得不到足夠的CPU資源。這時可以考慮將當前虛擬機搬遷到其它的主機上,或者想辦法降低當前主機的負載,比如關掉一些其它的虛擬機。
總結
load average和%Cpu(s)以不同的方式給出了當前主機的CPU負載情況,通過%Cpu(s)我們可以看到系統當前的實時負載,現在很多監控系統每隔一段時間都會采集一次%Cpu(s),然后存儲起來以圖形的方式展示出來,對每個節點做負載監控很重要,防止節點出現問題。