CPU使用率低負載高
原因總結
產生的原因一句話總結就是:
等待磁碟I/O完成的程式過多,導致程式佇列長度過大,但是cpu執行的程式卻很少,這樣就體現到負載過大了,cpu使用率低。
下面內容是具體的原理分析:
在分析負載為什麼高之前先介紹下什麼是負載、多工作業系統、程式排程等相關概念。
什麼是負載
什麼是負載:負載就是cpu在一段時間內正在處理以及等待cpu處理的程式數之和的統計資訊,也就是cpu使用佇列的長度統計資訊,這個數字越小越好(如果超過CPU核心*0.7就是不正常)
負載分為兩大部分:CPU負載、IO負載
例如,假設有一個進行大規模科學計算的程式,雖然該程式不會頻繁地從磁碟輸入輸出,但是處理完成需要相當長的時間。因為該程式主要被用來做計算、邏輯判斷等處理,所以程式的處理速度主要依賴於cpu的計算速度。此類cpu負載的程式稱為“計算密集型程式”。
還有一類程式,主要從磁碟儲存的大量資料中搜尋找出任意檔案。這個搜尋程式的處理速度並不依賴於cpu,而是依賴於磁碟的讀取速度,也就是輸入輸出(input/output,I/O).磁碟越快,檢索花費的時間就越短。此類I/O負載的程式,稱為“I/O密集型程式”。
什麼是多工作業系統
Linux作業系統能夠同時處理幾個不同名稱的任務。但是同時執行多個任務的過程中,cpu和磁碟這些有限的硬體資源就需要被這些任務程式共享。即便很短的時間間隔內,需要一邊在這些任務之間進行切換到一邊進行處理,這就是多工。
執行中的任務較少的情況下,系統並不是等待此類切換動作的發生。但是當任務增加時,例如任務A正在CPU上執行計算,接下來如果任務B和C也想進行計算,那麼就需要等待CPU空閒。也就是說,即便是執行處理某任務,也要等到輪到他時才能執行,此類等待狀態就表現為程式執行延遲。
uptime輸出中包含“load average”的數字
[root@localhost ~]# uptime
11:16:38 up 2:06, 4 users, load average: 0.00, 0.02, 0.05
Load average從左邊起依次是過去1分鐘、5分鐘、15分鐘內,單位時間的等待任務數,也就是表示平均有多少任務正處於等待狀態。在load average較高的情況下,這就說明等待執行的任務較多,因此輪到該任務執行的等待時間就會出現較大的延遲,即反映了此時負載較高。
程式排程
什麼是程式排程:
程式排程也被一些人稱為cpu上下文切換意思是:CPU切換到另一個程式需要儲存當前程式的狀態並恢復另一個程式的狀態:當前執行任務轉為就緒(或者掛起、中斷)狀態,另一個被選定的就緒任務成為當前任務。程式排程包括儲存當前任務的執行環境,恢復將要執行任務的執行環境。
在linux核心中,每一個程式都存在一個名為“程式描述符”的管理表。該程式描述符會調整為按照優先順序降序排序,已按合理的順序執行程式(任務)。這個調整即為程式排程器的工作。
排程器劃分並管理程式的狀態,如:
- 等待分配cpu資源的狀態。
- 等待磁碟輸入輸出完畢的狀態。
下面在說一下程式的狀態區別:
狀態 |
說明 |
執行態(running) |
只要cpu空閒,任何時候都可以執行 |
可中斷睡眠(interruptible) |
為恢復時間無法預測的長時間等待狀態。如,來自於鍵盤裝置的輸入。 |
不可中斷睡眠:(uninterruptible) |
主要為短時間時的等待狀態。例如磁碟輸入輸出等待。被IO阻塞的程式 |
就緒態(runnable) |
響應暫停訊號而執行的中斷狀態。 |
僵死態(zombie) |
程式都是由父程式建立,並銷燬;在父程式沒有銷燬其子程式,被銷燬的時候,其子程式由於沒有父程式被銷燬,就會轉變為僵死態。 |
下面舉例來說明程式狀態轉變:
這裡有三個程式A、B、C同時執行。首先,每個程式在生成後都是可執行狀態,也就是running狀態的開始,而不是現在執行狀態,由於在linux核心中無法區別正在執行的狀態和可執行的等待狀態,下面將可執行狀態和正在執行狀態都稱為running狀態。
- 程式A:running
- 程式B:running
- 程式C:running
running的三個程式立即成為排程物件。此時,假設排程器給程式A分配了CPU的執行許可權。
- 程式A:running (正在執行)
- 程式B:running
- 程式C:running
程式A分配了CPU,所以程式A開始處理。程式B和C則在此等待程式A遷出CPU。假設程式A進行若干計算之後,需要從磁碟讀取資料。那麼在A發出讀取磁碟資料的請求之後,到請求資料到達之前,將不進行任何工作。此狀態稱為“因等待I/O操作結束而被阻塞”。在I/O完成處理前,程式A就一直處於等待中,就會轉為不可中斷睡眠狀態(uninterruptible),並不使用CPU。於是排程器檢視程式B和程式C的優先順序計算結果,將CPU執行許可權交給優先順序較高的一方。這裡假設程式B的優先順序高於程式C。
- 程式A:uninterruptible (等待磁碟輸入輸出/不可中斷狀態)
- 程式B:running (正在執行)
- 程式C:running
程式B剛開始執行,就需要等待使用者的鍵盤輸入。於是B進入等待使用者鍵盤輸入狀態,同樣被阻塞。結果就變成了程式A和程式B都是等待輸出,執行程式C。這時程式A和程式B都是等待狀態,但是等待磁碟輸入輸出和等待鍵盤輸入為不同的狀態。等待鍵盤輸入是無限期的事件等待,而讀取磁碟則是必須短時間內完成的事件等待,這是兩種不同的等待狀態。各程式狀態如下所示:
- 程式A:uninterruptible (等待磁碟輸入輸出/不可中斷狀態)
- 程式B:interruptible (等待鍵盤輸入輸出/可中斷狀態)
- 程式C:running (正在執行)
這次假設程式C在執行的過程中,程式A請求的資料從磁碟到達了緩衝裝置。緊接著硬碟對核心發起中斷訊號,核心知道磁碟讀取完成,將程式A恢復為可執行狀態。
- 程式A:running (正在執行)
- 程式B:interruptible (等待鍵盤輸入輸出/可中斷狀態)
- 程式C:running (正在執行)
此後程式C也會變為某種等待狀態。如CPU的佔用時間超出了上限、任務結束、進入I/O等待。一旦滿足這些條件,排程器就可以完成從程式C到程式A的程式狀態切換。
負載的意義:
負載表示的是“等待程式的平均數”。在上面的程式狀態變換過程中,除了running狀態,其他都是等待狀態,那麼其他狀態都會加入到負載等待程式中嗎?
事實證明,只有程式處於執行態(running)和不可中斷狀態(interruptible)才會被加入到負載等待程式中,也就是下面這兩種情況的程式才會表現為負載的值。
- 即便需要立即使用CPU,也還需等待其他程式用完CPU
- 即便需要繼續處理,也必須等待磁碟輸入輸出完成才能進行
下面描述一種直觀感受的場景說明為什麼只有執行態(running)和可中斷狀態(interruptible)才會被加入負載。
如:在很佔用CPU資源的處理中,例如在進行動畫編碼的過程中,雖然想進行其他相同型別的處理,結果系統反映卻變得很慢,還有從磁碟讀取大量資料時,系統的反映也同樣會變的很慢。但是另一方面,無論有多少等待鍵盤輸入輸出操作的程式,也不會讓系統響應變慢。
什麼場景會造成CPU低而負載確很高呢?
透過上面的具體分析負載的意義就很明顯了,負載總結為一句話就是:需要執行處理但又必須等待佇列前的程式處理完成的程式個數。具體來說,也就是如下兩種情況:
- 等待被授權予CPU執行許可權的程式
- 等待磁碟I/O完成的程式
cpu低而負載高也就是說等待磁碟I/O完成的程式過多,就會導致佇列長度過大,這樣就體現到負載過大了,但實際是此時cpu被分配去執行別的任務或空閒,具體場景有如下幾種。
場景一:磁碟讀寫請求過多就會導致大量I/O等待
上面說過,cpu的工作效率要高於磁碟,而程式在cpu上面執行需要訪問磁碟檔案,這個時候cpu會向核心發起呼叫檔案的請求,讓核心去磁碟取檔案,這個時候會切換到其他程式或者空閒,這個任務就會轉換為不可中斷睡眠狀態。當這種讀寫請求過多就會導致不可中斷睡眠狀態的程式過多,從而導致負載高,cpu低的情況。
場景二:MySQL中存在沒有索引的語句或存在死鎖等情況
我們都知道MySQL的資料是儲存在硬碟中,如果需要進行sql查詢,需要先把資料從磁碟載入到記憶體中。當在資料特別大的時候,如果執行的sql語句沒有索引,就會造成掃描表的行數過大導致I/O阻塞,或者是語句中存在死鎖,也會造成I/O阻塞,從而導致不可中斷睡眠程式過多,導致負載過大。
具體解決方法可以在MySQL中執行show full processlist命令檢視執行緒等待情況,把其中的語句拿出來進行最佳化。
場景三:外接硬碟故障,常見有掛了NFS,但是NFS server故障
比如我們的系統掛載了外接硬碟如NFS共享儲存,經常會有大量的讀寫請求去訪問NFS儲存的檔案,如果這個時候NFS Server故障,那麼就會導致程式讀寫請求一直獲取不到資源,從而程式一直是不可中斷狀態,造成負載很高。
理解Linux系統負荷
一、檢視系統負荷
如果你的電腦很慢,你或許想檢視一下,它的工作量是否太大了。
在Linux系統中,我們一般使用uptime命令檢視(w命令和top命令也行)。(另外,它們在蘋果公司的Mac電腦上也適用。)
你在終端視窗鍵入uptime,系統會返回一行資訊。
這行資訊的後半部分,顯示"load average",它的意思是"系統的平均負荷",裡面有三個數字,我們可以從中判斷系統負荷是大還是小。
為什麼會有三個數字呢?你從手冊中查到,它們的意思分別是1分鐘、5分鐘、15分鐘內系統的平均負荷。
如果你繼續看手冊,它還會告訴你,當CPU完全空閒的時候,平均負荷為0;當CPU工作量飽和的時候,平均負荷為1。
那麼很顯然,"load average"的值越低,比如等於0.2或0.3,就說明電腦的工作量越小,系統負荷比較輕。
但是,什麼時候能看出系統負荷比較重呢?等於1的時候,還是等於0.5或等於1.5的時候?如果1分鐘、5分鐘、15分鐘三個值不一樣,怎麼辦?
二、一個類比
判斷系統負荷是否過重,必須理解load average的真正含義。下面,我根據"
Understanding Linux CPU Load"這篇文章,嘗試用最通俗的語言,解釋這個問題。
首先,假設最簡單的情況,你的電腦只有一個CPU,所有的運算都必須由這個CPU來完成。
那麼,我們不妨把這個CPU想象成一座大橋,橋上只有一根車道,所有車輛都必須從這根車道上透過。(很顯然,這座橋只能單向通行。)
系統負荷為0,意味著大橋上一輛車也沒有。
系統負荷為0.5,意味著大橋一半的路段有車。
系統負荷為1.0,意味著大橋的所有路段都有車,也就是說大橋已經"滿"了。但是必須注意的是,直到此時大橋還是能順暢通行的。
系統負荷為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,會發生什麼情況呢?
2個CPU,意味著電腦的處理能力翻了一倍,能夠同時處理的程式數量也翻了一倍。
還是用大橋來類比,兩個CPU就意味著大橋有兩根車道了,通車能力翻倍了。
所以,2個CPU表明系統負荷可以達到2.0,此時每個CPU都達到100%的工作量。推廣開來,n個CPU的電腦,可接受的系統負荷最大為n.0。
五、多核處理器
晶片廠商往往在一個CPU內部,包含多個CPU核心,這被稱為多核CPU。
在系統負荷方面,多核CPU與多CPU效果類似,所以考慮系統負荷的時候,必須考慮這臺電腦有幾個CPU、每個CPU有幾個核心。然後,把系統負荷除以總的核心數,只要每個核心的負荷不超過1.0,就表明電腦正常執行。
怎麼知道電腦有多少個CPU核心呢?
"cat /proc/cpuinfo"命令,可以檢視CPU資訊。"grep -c 'model name' /proc/cpuinfo"命令,直接返回CPU的總核心數。
六、最佳觀察時長
最後一個問題,"load average"一共返回三個平均值----1分鐘系統負荷、5分鐘系統負荷,15分鐘系統負荷,----應該參考哪個值?
如果只有1分鐘的系統負荷大於1.0,其他兩個時間段都小於1.0,這表明只是暫時現象,問題不大。
如果15分鐘內,平均系統負荷大於1.0(調整CPU核心數之後),表明問題持續存在,不是暫時現象。所以,你應該主要觀察"15分鐘系統負荷",將它作為電腦正常執行的指標。
==========================================
[參考文獻]
1.
Understanding Linux CPU Load
2.
如果你的Linux伺服器突然負載暴增,告警簡訊快發爆你的手機,如何在最短時間內找出Linux效能問題所在?Netflix效能工程團隊的Brendan Gregg寫下了這篇博文,來看他們是怎樣透過十條命令在一分鐘內對機器效能問題進行診斷。
概述
透過執行以下命令,可以在1分鐘內對系統資源使用情況有個大致的瞭解。
其中一些命令需要安裝sysstat包,有一些由procps包提供。這些命令的輸出,有助於快速定位效能瓶頸,檢查出所有資源(CPU、記憶體、磁碟IO等)的利用率(utilization)、飽和度(saturation)和錯誤(error)度量,也就是所謂的USE方法。
下面我們來逐一介紹下這些命令,有關這些命令更多的引數和說明,請參照命令的手冊。
23:51:26 up 21:31, 1 user, load average: 30.02, 26.43, 19.02
這個命令可以快速檢視機器的負載情況。在Linux系統中,這些資料表示等待CPU資源的程式和阻塞在不可中斷IO程式(程式狀態為D)的數量。這些資料可以讓我們對系統資源使用有一個宏觀的瞭解。
命令的輸出分別表示1分鐘、5分鐘、15分鐘的平均負載情況。透過這三個資料,可以瞭解伺服器負載是在趨於緊張還是區域緩解。如果1分鐘平均負載很高,而15分鐘平均負載很低,說明伺服器正在命令高負載情況,需要進一步排查CPU資源都消耗在了哪裡。反之,如果15分鐘平均負載很高,1分鐘平均負載較低,則有可能是CPU資源緊張時刻已經過去。
上面例子中的輸出,可以看見最近1分鐘的平均負載非常高,且遠高於最近15分鐘負載,因此我們需要繼續排查當前系統中有什麼程式消耗了大量的資源。可以透過下文將會介紹的vmstat、mpstat等命令進一步排查。
[1880957.563150] perl invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0
[1880957.563400] Out of memory: Kill process 18694 (perl) score 246 or sacrifice child
[1880957.563408] Killed process 18694 (perl) total-vm:1972392kB, anon-rss:1953348kB, file-rss:0kB
[2320864.954447] TCP: Possible SYN flooding on port 7001. Dropping request. Check SNMP counters.
該命令會輸出系統日誌的最後10行。示例中的輸出,可以看見一次核心的oom kill和一次TCP丟包。這些日誌可以幫助排查效能問題。千萬不要忘了這一步。
procs ---------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
34 0 0 200889792 73708 591828 0 0 0 5 6 10 96 1 3 0 0
32 0 0 200889920 73708 591860 0 0 0 592 13284 4282 98 1 1 0 0
32 0 0 200890112 73708 591860 0 0 0 0 9501 2154 99 1 0 0 0
32 0 0 200889568 73712 591856 0 0 0 48 11900 2459 99 0 0 0 0
32 0 0 200890208 73712 591860 0 0 0 0 15898 4840 98 1 1 0 0
vmstat(8) 命令,每行會輸出一些系統核心指標,這些指標可以讓我們更詳細的瞭解系統狀態。後面跟的引數1,表示每秒輸出一次統計資訊,表頭提示了每一列的含義,這幾介紹一些和效能調優相關的列:
-
r:等待在CPU資源的程式數。這個資料比平均負載更加能夠體現CPU負載情況,資料中不包含等待IO的程式。如果這個數值大於機器CPU核數,那麼機器的CPU資源已經飽和。
-
free:系統可用記憶體數(以千位元組為單位),如果剩餘記憶體不足,也會導致系統效能問題。下文介紹到的free命令,可以更詳細的瞭解系統記憶體的使用情況。
-
si, so:交換區寫入和讀取的數量。如果這個資料不為0,說明系統已經在使用交換區(swap),機器實體記憶體已經不足。
-
us, sy, id, wa, st:這些都代表了CPU時間的消耗,它們分別表示使用者時間(user)、系統(核心)時間(sys)、空閒時間(idle)、IO等待時間(wait)和被偷走的時間(stolen,一般被其他虛擬機器消耗)。
上述這些CPU時間,可以讓我們很快了解CPU是否出於繁忙狀態。一般情況下,如果使用者時間和系統時間相加非常大,CPU出於忙於執行指令。如果IO等待時間很長,那麼系統的瓶頸可能在磁碟IO。
示例命令的輸出可以看見,大量CPU時間消耗在使用者態,也就是使用者應用程式消耗了CPU時間。這不一定是效能問題,需要結合r佇列,一起分析。
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
07:38:49 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
07:38:50 PM all 98.47 0.00 0.75 0.00 0.00 0.00 0.00 0.00 0.00 0.78
07:38:50 PM 0 96.04 0.00 2.97 0.00 0.00 0.00 0.00 0.00 0.00 0.99
07:38:50 PM 1 97.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 2.00
07:38:50 PM 2 98.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00
07:38:50 PM 3 96.97 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.03
該命令可以顯示每個CPU的佔用情況,如果有一個CPU佔用率特別高,那麼有可能是一個單執行緒應用程式引起的。
$ pidstat 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
07:41:02 PM UID PID %usr %system %guest %CPU CPU Command
07:41:03 PM 0 9 0.00 0.94 0.00 0.94 1 rcuos/0
07:41:03 PM 0 4214 5.66 5.66 0.00 11.32 15 mesos-slave
07:41:03 PM 0 4354 0.94 0.94 0.00 1.89 8 java
07:41:03 PM 0 6521 1596.23 1.89 0.00 1598.11 27 java
07:41:03 PM 0 6564 1571.70 7.55 0.00 1579.25 28 java
07:41:03 PM 60004 60154 0.94 4.72 0.00 5.66 9 pidstat
07:41:03 PM UID PID %usr %system %guest %CPU CPU Command
07:41:04 PM 0 4214 6.00 2.00 0.00 8.00 15 mesos-slave
07:41:04 PM 0 6521 1590.00 1.00 0.00 1591.00 27 java
07:41:04 PM 0 6564 1573.00 10.00 0.00 1583.00 28 java
07:41:04 PM 108 6718 1.00 0.00 0.00 1.00 0 snmp-pass
07:41:04 PM 60004 60154 1.00 4.00 0.00 5.00 9 pidstat
^C
pidstat命令輸出程式的CPU佔用率,該命令會持續輸出,並且不會覆蓋之前的資料,可以方便觀察系統動態。如上的輸出,可以看見兩個JAVA程式佔用了將近1600%的CPU時間,既消耗了大約16個CPU核心的運算資源。
$ iostat -xz 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
73.96 0.00 3.73 0.03 0.06 22.21
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
xvda 0.00 0.23 0.21 0.18 4.52 2.08 34.37 0.00 9.98 13.80 5.42 2.44 0.09
xvdb 0.01 0.00 1.02 8.94 127.97 598.53 145.79 0.00 0.43 1.78 0.28 0.25 0.25
xvdc 0.01 0.00 1.02 8.86 127.79 595.94 146.50 0.00 0.45 1.82 0.30 0.27 0.26
dm-0 0.00 0.00 0.69 2.32 10.47 31.69 28.01 0.01 3.23 0.71 3.98 0.13 0.04
dm-1 0.00 0.00 0.00 0.94 0.01 3.78 8.00 0.33 345.84 0.04 346.81 0.01 0.00
dm-2 0.00 0.00 0.09 0.07 1.35 0.36 22.50 0.00 2.55 0.23 5.62 1.78 0.03
[...]
^C
iostat命令主要用於檢視機器磁碟IO情況。該命令輸出的列,主要含義是:
-
r/s, w/s, rkB/s, wkB/s:分別表示每秒讀寫次數和每秒讀寫資料量(千位元組)。讀寫量過大,可能會引起效能問題。
-
await:IO操作的平均等待時間,單位是毫秒。這是應用程式在和磁碟互動時,需要消耗的時間,包括IO等待和實際操作的耗時。如果這個數值過大,可能是硬體裝置遇到了瓶頸或者出現故障。
-
avgqu-sz:向裝置發出的請求平均數量。如果這個數值大於1,可能是硬體裝置已經飽和(部分前端硬體裝置支援並行寫入)。
-
%util:裝置利用率。這個數值表示裝置的繁忙程度,經驗值是如果超過60,可能會影響IO效能(可以參照IO操作平均等待時間)。如果到達100%,說明硬體裝置已經飽和。
如果顯示的是邏輯裝置的資料,那麼裝置利用率不代表後端實際的硬體裝置已經飽和。值得注意的是,即使IO效能不理想,也不一定意味這應用程式效能會不好,可以利用諸如預讀取、寫快取等策略提升應用效能。
$ free -m
total used free shared buffers cached
Mem: 245998 24545 221453 83 59 541
-/+ buffers/cache: 23944 222053
Swap: 0 0 0
free命令可以檢視系統記憶體的使用情況,-m參數列示按照兆位元組展示。最後兩列分別表示用於IO快取的記憶體數,和用於檔案系統頁快取的記憶體數。需要注意的是,第二行-/+ buffers/cache,看上去快取佔用了大量記憶體空間。這是Linux系統的記憶體使用策略,儘可能的利用記憶體,如果應用程式需要記憶體,這部分記憶體會立即被回收並分配給應用程式。因此,這部分記憶體一般也被當成是可用記憶體。
如果可用記憶體非常少,系統可能會動用交換區(如果配置了的話),這樣會增加IO開銷(可以在iostat命令中提現),降低系統效能。
$ sar -n DEV 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
12:16:48 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
12:16:49 AM eth0 18763.00 5032.00 20686.42 478.30 0.00 0.00 0.00 0.00
12:16:49 AM lo 14.00 14.00 1.36 1.36 0.00 0.00 0.00 0.00
12:16:49 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:16:49 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
12:16:50 AM eth0 19763.00 5101.00 21999.10 482.56 0.00 0.00 0.00 0.00
12:16:50 AM lo 20.00 20.00 3.25 3.25 0.00 0.00 0.00 0.00
12:16:50 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
^C
sar命令在這裡可以檢視網路裝置的吞吐率。在排查效能問題時,可以透過網路裝置的吞吐量,判斷網路裝置是否已經飽和。如示例輸出中,eth0網路卡裝置,吞吐率大概在22 Mbytes/s,既176 Mbits/sec,沒有達到1Gbit/sec的硬體上限。
$ sar -n TCP,ETCP 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
12:17:19 AM active/s passive/s iseg/s oseg/s
12:17:20 AM 1.00 0.00 10233.00 18846.00
12:17:19 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
12:17:20 AM 0.00 0.00 0.00 0.00 0.00
12:17:20 AM active/s passive/s iseg/s oseg/s
12:17:21 AM 1.00 0.00 8359.00 6039.00
12:17:20 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
12:17:21 AM 0.00 0.00 0.00 0.00 0.00
^C
sar命令在這裡用於檢視TCP連線狀態,其中包括:
TCP連線數可以用來判斷效能問題是否由於建立了過多的連線,進一步可以判斷是主動發起的連線,還是被動接受的連線。TCP重傳可能是因為網路環境惡劣,或者伺服器壓力過大導致丟包。
$ top
top - 00:15:40 up 21:56, 1 user, load average: 31.09, 29.87, 29.92
Tasks: 871 total, 1 running, 868 sleeping, 0 stopped, 2 zombie
%Cpu(s): 96.8 us, 0.4 sy, 0.0 ni, 2.7 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 25190241+total, 24921688 used, 22698073+free, 60448 buffers
KiB Swap: 0 total, 0 used, 0 free. 554208 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20248 root 20 0 0.227t 0.012t 18748 S 3090 5.2 29812:58 java
4213 root 20 0 2722544 64640 44232 S 23.5 0.0 233:35.37 mesos-slave
66128 titancl+ 20 0 24344 2332 1172 R 1.0 0.0 0:00.07 top
5235 root 20 0 38.227g 547004 49996 S 0.7 0.2 2:02.74 java
4299 root 20 0 20.015g 2.682g 16836 S 0.3 1.1 33:14.42 java
1 root 20 0 33620 2920 1496 S 0.0 0.0 0:03.82 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.02 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:05.35 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
6 root 20 0 0 0 0 S 0.0 0.0 0:06.94 kworker/u256:0
8 root 20 0 0 0 0 S 0.0 0.0 2:38.05 rcu_sched
top命令包含了前面好幾個命令的檢查的內容。比如系統負載情況(uptime)、系統記憶體使用情況(free)、系統CPU使用情況(vmstat)等。因此透過這個命令,可以相對全面的檢視系統負載的來源。同時,top命令支援排序,可以按照不同的列排序,方便查詢出諸如記憶體佔用最多的程式、CPU佔用率最高的程式等。
但是,top命令相對於前面一些命令,輸出是一個瞬間值,如果不持續盯著,可能會錯過一些線索。這時可能需要暫停top命令重新整理,來記錄和比對資料。
總結
排查Linux伺服器效能問題還有很多工具,上面介紹的一些命令,可以幫助我們快速的定位問題。例如前面的示例輸出,多個證據證明有JAVA程式佔用了大量CPU資源,之後的效能調優就可以針對應用程式進行。
About Me
|
|
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2686807/,如需轉載,請註明出處,否則將追究法律責任。