效能分析的目標是改善使用者體驗、降低執行成本。效能分析的方法論可以指導你進行這些選擇,告訴你從哪裡開始,一步步分析,最後在哪裡結束。
本文選自《BPF之巔:洞悉Linux系統和應用效能》一書,將向你介紹一個Linux 下的 60 秒分析的檢查清單,你在做日常效能分析工作時可以首先使用它~它能直接幫助你快速定位效能問題,或者至少提供進一步使用哪些 BPF 工具進行分析的線索。
60秒清單
這個清單適用於任何效能問題的分析工作,也反映了筆者在實際工作中,當登入到一臺表現不佳的 Linux 系統中後,在最初 60 秒內通常會進行的操作。
要執行的工具是 :
1. uptime
2. dmesg | tail
3. vmstat 1
4. mpstat -P ALL 1
5. pidstat 1
6. iostat -xz 1
7. free -m
8. sar -n DEV 1
9. sar -n TCP,ETCP 1
10. top
下面的我們會依次介紹每個工具。這些命令有可能會幫助你快速直接定位出效能問題。即便不能的話,這些工具也能暴露問題根源的線索,以便指引你後續使用 BPF 工具進一步定位真正的問題。
1.uptime
1$ uptime2 03:16:59 up 17 days, 4:18, 1 user, load average: 2.74, 2.54, 2.58
這個工具可以快速檢查平均負載,也就是有多少個任務(程序)需要執行。在Linux 系統中,這些數字包含了想要在 CPU 上執行的程序,同時也包含了阻塞在不可中斷 I/O(通常是磁碟 I/O)上的程序。這給出了一個高層次視角的資源負載(或者說資源需求),在此之後可以透過其他工具進行進一步檢查。
這 3 個數字分別是指數衰減的 1 分鐘 /5 分鐘 /15 分鐘滑動視窗累積值。透過這 3 個值可以大致瞭解負載隨時間變化的情況。上面的例子顯示負載最近有小幅的提升。
負載的平均值值得在排障過程中被首先進行檢查,以確認效能問題是否還存在。在一個容錯的環境中,一臺存在效能問題的伺服器,在你登入到機器上時,也許已經自動從服務列表中下線了。一個較高的 15 分鐘負載與一個較低的 1 分鐘負載同時出現,可能意味著已經錯過了問題發生的現場。
2. dmesg | tail
1$ dmesg | tail2[1880957.563150] perl invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=03[...]4[1880957.563400] Out of memory: Kill process 18694 (perl) score 246 or sacrifice child5[1880957.563408] Killed process 18694 (perl) total-vm:1972392kB, anon-rss:1953348kB, 6file-rss:0kB7[2320864.954447] TCP: Possible SYN flooding on port 7001. Dropping request. Check SNMP 8counters.
這個命令可以顯示過去 10 條系統日誌。注意在這裡尋找可能導致效能問題的錯誤。這個例子顯示了記憶體不足引發 OOM 和 TCP 的丟棄請求的記錄。TCP 的相關日誌甚至指引了我們下一步的分析方向 :檢視 SNMP 計數器值。
3. vmstat 1
這個虛擬記憶體統計工具最早源於 BSD,同時還展示了一些其他的系統指標。當執行時帶著命令列引數 1 時,會隔 1 秒列印一次摘要資訊 ;注意,第 1 行輸出的數字是自系統啟動後的統計值(記憶體相關的計數器除外)。
需要檢查的列包括如下幾個。
r :CPU 上正在執行的和等待執行的程序數量。相比平均負載來說,這是一個更好的排查 CPU 飽和度的指標,因為它不包含 I/O。可以這樣解釋 :一個比 CPU數量多的 r 值代表 CPU 資源處於飽和狀態。
free :空閒記憶體,單位是KB。如果數字位數一眼數不過來,那麼記憶體應該是夠用的。使用 free -m 命令,可以更好地解釋空閒記憶體。
si 和 so :頁換入和頁換出。如果這些值不是零,那麼意味著系統記憶體緊張。這個值只有在配置開啟了交換分割槽後才會起作用。
us、sy、id、wa 和 st :這些都是 CPU 執行時間的進一步細分,是對所有的CPU 取平均之後的結果。它們分別代表使用者態時間、系統態時間(核心)、空閒、等待 I/O,以及被竊取時間(stolen time,指的是虛擬化環境下,被其他客戶機所擠佔的時間 ;或者是 Xen 環境下客戶機自身隔離的驅動域執行時間)。
上面的例子顯示了 CPU 時間主要花在使用者態上。這指引我們下一步將主要針對使用者態程式碼進行剖析。
4. mpstat -P ALL 1
這個命令將每個 CPU 分解到各個狀態下的時間打印出來。上面的輸出暴露了一個問題 :CPU 0 的使用者態的佔比高達 100%,這是單個執行緒遇到瓶頸的特徵。
對於比較高的 %iowait 時間也要注意,可以使用磁碟 I/O 工具進一步分析 ;如果出現較高的 %sys 值,可以使用系統呼叫(syscall)跟蹤和核心跟蹤,以及 CPU 剖析等手段進一步分析。
5. pidstat 1
pidstat(1) 命令按每個程序展示 CPU 的使用情況。top(1) 命令雖然也很流行,但是pidstat(1) 預設支援滾動列印輸出,這樣可以採集到不同時間段的資料變化。這個輸出顯示了一個 Java 程序每秒使用的 CPU 資源在變化 ;這個百分比是對全部 CPU 相加的和 ,因此 500% 相當於 5 個 100% 執行的 CPU。
注意,最近pidstat(1)有一個修改,即將其百分比的上限定在100%。這在多執行緒的情況下,可能會導致錯誤的輸出。儘管這個改動已經被撤回了,但還是提醒你注意一下是否使用了有錯誤改動的pidstat(1)版本。
6. iostat -xz 1
這個工具顯示了儲存裝置的 I/O 指標。上面的每個磁碟裝置輸出行由於過長進行了換行,閱讀起來稍顯不便。
要檢查的列包括如下幾個。
r/s、w/s、rkB/s 和 wkB/s:這些是每秒向裝置傳送的讀、寫次數,以及讀、寫位元組數。可以用這些指標對業務負載畫像。某些效能問題僅僅是因為超過了能夠承受的最大負載導致的。
await :I/O 的平均響應時間,以毫秒為單位。這是應用需要承受的時間,它同時包含了 I/O 佇列時間和服務時間。超過預期的平均響應時間,可看作裝置已飽和或者裝置層面有問題的表徵。
avgqu-sz :裝置請求佇列的平均長度。比 1 大的值有可能是發生飽和的表徵(不過對有些裝置,尤其是對基於多塊磁碟的虛擬裝置來說,通常以並行方式處理請求)。
%util :裝置使用率。這是裝置繁忙程度的百分比,顯示了每秒裝置開展實際工作的時間佔比。不過它展示的並不是容量規劃意義下的使用率,因為裝置可以並行處理請求。大於 60% 的值通常會導致效能變差(可以透過 await 欄位確認),不過這也取決於具體裝置。接近 100% 的值通常代表了裝置達到飽和狀態。
注意,這有時會引起困惑,比如當iostat(1)報告說某個裝置已經達到100%的使用率後,還能夠接受更高的負載。它只是報告某個裝置在一段時間內100%繁忙,並沒有說裝置的使用率達到100%了:此時也許仍然可以接受更高的負載。在一個卷後面有多個磁碟裝置支撐的情況下由於可以並行處理請求,iostat(1)中的%util這個指標就更加具有迷惑性。
上面的輸出顯示了向 md0 虛擬裝置的寫入負載約為 300MB/s,看起來 md0 的背後是兩塊 nvme 裝置。
7. free -m
這個輸出顯示了用兆位元組(MB)作為單位的可用記憶體。檢查可用記憶體(available)是否接近 0 ;這個值顯示了在系統中還有多少實際剩餘記憶體可用,包括緩衝區和頁快取區。將一些記憶體用於快取可以提升檔案系統的效能。
注意,free(1) 命令的輸出格式最近也有修改。
過去是把 buff 和 cache欄位分開列出,並且沒有 available 欄位,使用者需要時要自行計算available的值。筆者更喜歡新版的輸出。如果想分開展示 buff 和 cache,可以使用命令列引數-w開啟寬屏模式。
8. sar -n DEV 1
將不同的指標進行組合,sar(1) 工具有不同的執行模式。在這個例子中,筆者使用它來檢視網路裝置指標。透過介面吞吐量資訊 rxkB/s 和 txkB/s 來檢查是否有指標達到了上限。
9. sar -n TCP,ETCP 1
現在我們使用 sar(1) 工具來檢視 TCP 指標和 TCP 錯誤資訊。相關的欄位包括如下幾個。
active/s :每秒本地發起的 TCP 連線的數量(透過呼叫 connect() 建立)。
passive/s :每秒遠端發起的 TCP 連線的數量(透過呼叫 accept() 建立)。
retrans/s :每秒 TCP 重傳的數量。
主動和被動連線計數對於業務負載畫像很有用。重傳則是網路或者遠端主機有問題的徵兆。
10. top
至此,你已經使用前面列舉的工具看到了很多指標。不過再多做一步會更有益 :我們以 top 命令作為結束,對相關結果進行二次確認,並能夠瀏覽系統和程序的摘要資訊。運氣好的話,這個 60 秒分析過程會幫助你找到一些效能問題的線索。在此基礎上,可以使用專門的 BPF 工具開展進一步分析。
BPF之巔
▊《BPF之巔:洞悉Linux系統和應用效能》
【美】Brendan Gregg 著
孫宇聰 呂宏利 劉曉舟 譯
● Gregg大師新作,《效能之巔》再續新篇
● 效能最佳化的萬用金典,150+分析除錯工具深度剖析
本書作為全面介紹 BPF 技術的圖書,從 BPF 技術的起源到未來發展方向都有涵蓋,不僅全面介紹了 BPF 的程式設計模型,還完整介紹了兩個主要的 BPF 前端程式設計框架 — BCC 和 bpftrace,更給出了一系列實現範例,生動展示了 BPF技術的實際能力和未來發展前景。