1. 常用的一些系統性能排查linux命令
一、CPU
首先介紹計算機中最重要的計算元件中央處理器 CPU,圍繞 CPU 一般我們可以:
-
通過 top 命令,來觀測 CPU 的效能;
-
通過負載,評估 CPU 任務執行的排隊情況;
-
通過 vmstat,看 CPU 的繁忙程度。
1.1 top命令--CPU效能
如下圖,當進入 top 命令後,按 1 鍵即可看到每核 CPU 的執行指標和詳細效能。
CPU 的使用有多個維度的指標,下面分別說明
us 使用者態所佔用的 CPU 百分比,即引用程式所耗費的 CPU;
sy 核心態所佔用的 CPU 百分比,需要配合 vmstat 命令,檢視上下文切換是否頻繁;
ni 高優先順序應用所佔用的 CPU 百分比;
wa 等待 I/O 裝置所佔用的 CPU 百分比,經常使用它來判斷 I/O 問題,過高輸入輸出裝置可能存在非常明顯的瓶頸;
hi 硬中斷所佔用的 CPU 百分比;
si 軟中斷所佔用的 CPU 百分比;
st 在平常的伺服器上這個值很少發生變動,因為它測量的是宿主機對虛擬機器的影響,即虛擬機器等待宿主機 CPU 的時間佔比,這在一些超賣的雲伺服器上,經常發生;
id 空閒 CPU 百分比。
一般地,我們比較關注空閒 CPU 的百分比,它可以從整體上體現 CPU 的利用情況。
那 load 為 1 代表的是啥?針對這個問題,誤解還是比較多的。
1.2 負載 —— CPU 任務排隊情況
如果我們評估 CPU 任務執行的排隊情況,那麼需要通過負載(load)來完成。除了 top 命令,使用 uptime 命令也能夠檢視負載情況,load 的效果是一樣的,分別顯示了最近 1min、5min、15min 的數值。
很多人看到 load 的值達到 1,就認為系統負載已經到了極限。這在單核的硬體上沒有問題,但在多核硬體上,這種描述就不完全正確,它還與 CPU 的個數有關。例如: 單核的負載達到 1,總 load 的值約為 1; 雙核的每核負載都達到 1,總 load 約為 2; 四核的每核負載都達到 1,總 load 約為 4。 所以,對於一個 load 到了 10,卻是 16 核的機器,你的系統還遠沒有達到負載極限。
1.3 vmstat —— CPU 繁忙程度
要看 CPU 的繁忙程度,可以通過 vmstat 命令,下圖是 vmstat 命令的一些輸出資訊。
比較關注的有下面幾列: b 如果系統有負載問題,就可以看一下 b 列(Uninterruptible Sleep),它的意思是等待 I/O,可能是讀盤或者寫盤動作比較多; si/so 顯示了交換分割槽的一些使用情況,交換分割槽對效能的影響比較大,需要格外關注; cs 每秒鐘上下文切換(Context Switch)的數量,如果上下文切換過於頻繁,就需要考慮是否是程序或者執行緒數開的過多。 每個程序上下文切換的具體數量,可以通過檢視記憶體對映檔案獲取,如下程式碼所示(voluntary_ctxt_switchesh和nonvoluntary_ctxt_switches):
二、記憶體
邏輯地址可以對映到兩個記憶體段上:實體記憶體和虛擬記憶體,那麼整個系統可用的記憶體就是兩者之和。比如你的實體記憶體是 4GB,分配了 8GB 的 SWAP 分割槽,那麼應用可用的總記憶體就是 12GB。
2.1 top命令
top命令開啟後,按f鍵如下所示,按Enter退出:
Current Fields
預設情況下僅顯示比較重要的 PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND 列。可以通過下面的快捷鍵來更改顯示內容。
-
通過 f 鍵可以選擇顯示的內容。按 f 鍵之後會顯示列的列表,按 a-z 即可顯示或隱藏對應的列,最後按回車鍵確定。
-
按 o 鍵可以改變列的顯示順序。按小寫的 a-z 可以將相應的列向右移動,而大寫的 A-Z 可以將相應的列向左移動。最後按回車鍵確定。
-
按大寫的 F 或 O 鍵,然後按 a-z 可以將程序按照相應的列進行排序。而大寫的 R 鍵可以將當前的排序倒轉。
top 執行中可以通過 top 的內部命令對程序的顯示方式進行控制。內部命令如下: s – 改變畫面更新頻率 l – 關閉或開啟第一部分第一行 top 資訊的表示 t – 關閉或開啟第一部分第二行 Tasks 和第三行 Cpus 資訊的表示 m – 關閉或開啟第一部分第四行 Mem 和 第五行 Swap 資訊的表示 N – 以 PID 的大小的順序排列表示程序列表 P – 以 CPU 佔用率大小的順序排列程序列表 M – 以記憶體佔用率大小的順序排列程序列表 h – 顯示幫助 n – 設定在程序列表所顯示程序的數量 q – 退出 top s – 改變畫面更新週期
三、IO
I/O 裝置可能是計算機裡速度最慢的元件了,它指的不僅僅是硬碟,還包括外圍的所有裝置。那硬碟有多慢呢?我們不去探究不同裝置的實現細節,直接看它的寫入速度(資料未經過嚴格測試,來自網路,僅作參考,在此只為了說明問題)。
如上圖所示,可以看到普通磁碟的隨機寫與順序寫相差非常大,但順序寫與 CPU 記憶體依舊不在一個數量級上。
緩衝區依然是解決速度差異的唯一工具,但在極端情況下,比如斷電時,就產生了太多的不確定性,這時這些緩衝區,都容易丟。
3.1 iostat
最能體現 I/O 繁忙程度的,就是 top 命令和 vmstat 命令中的 wa%。如果你的應用寫了大量的日誌,I/O wait 就可能非常高。
檢視磁碟 I/O 的工具(iostat), 如下所示:
圖中的指標詳細介紹如下所示。 %util:我們非常關注這個數值,通常情況下,這個數字超過 80%,就證明 I/O 的負荷已經非常嚴重了。 Device:表示是哪塊硬碟,如果你有多塊磁碟,則會顯示多行。 avgqu-sz:平均請求佇列的長度,這和十字路口排隊的汽車也非常類似。顯然,這個值越小越好。 awai:響應時間包含了佇列時間和服務時間,它有一個經驗值。通常情況下應該是小於 5ms 的,如果這個值超過了 10ms,則證明等待的時間過長了。 svctm:表示操作 I/O 的平均服務時間,這裡就是 AVG 的意思。svctm 和 await 是強相關的,如果它們比較接近,則表示 I/O 幾乎沒有等待,裝置的效能很好;但如果 await 比 svctm 的值高出很多,則證明 I/O 的佇列等待時間太長,進而系統上執行的應用程式將變慢。
3.2 零拷貝
硬碟上的資料,在發往網路之前,需要經過多次緩衝區的拷貝,以及使用者空間和核心空間的多次切換。如果能減少一些拷貝的過程,效率就能提升,所以零拷貝應運而生。 零拷貝是一種非常重要的效能優化手段,比如常見的 Kafka、Nginx 等,就使用了這種技術。我們來看一下有無零拷貝之間的區別。 (1)沒有采取零拷貝手段 如下圖所示,傳統方式中要想將一個檔案的內容通過 Socket 傳送出去,則需要經過以下步驟: 將檔案內容拷貝到核心空間; 將核心空間記憶體的內容,拷貝到使用者空間記憶體,比如 Java 應用讀取 zip 檔案; 使用者空間將內容寫入到核心空間的快取中; Socket 讀取核心快取中的內容,傳送出去。
(2)採取了零拷貝手段 零拷貝有多種模式,我們用 sendfile 來舉例。如下圖所示,在核心的支援下,零拷貝少了一個步驟,那就 是核心快取向用戶空間的拷貝,這樣既節省了記憶體,也節省了 CPU 的排程時間,讓效率更高。