在 Linux 上,可以使用 perf、pidstat 或 sar 等效能監控工具來測量單一程序的記憶體頻寬。CPU 和磁碟飽和通常能在 top 和 iostat 中直接看出來,而記憶體頻寬飽和卻不是如此。它往往隱藏在看似健康的 CPU 閒置率背後,甚至可能在一台 Linux 伺服器上持續數月而沒有明顯原因。請記住,top 和 ps 回報的是記憶體使用量,而不是記憶體吞吐量。若要找出究竟是哪個程序層級的負載讓記憶體頻寬長期處於飽和狀態,你需要一套專門的測量方法。本文將提供一套循序漸進的排查流程,包括指令使用方法與結果解讀,幫助系統管理員與 DevOps 工程師在任何伺服器上鎖定元兇、完成驗證,並在後續持續維持伺服器健康。

為什麼記憶體頻寬對伺服器如此重要

當 CPU 使用率低於預期,卻出現回應時間上升與查詢延遲增加時,這往往是某個程序造成記憶體頻寬飽和的典型訊號。在 Linux 伺服器上,這種現象可能持續數月。CPU 看似閒置,但每一個請求都要等待更久。在認定發生了頻寬飽和之前,你首先需要一個參考基準。

飽和的典型症狀

如果一個高執行緒數的負載無法隨著核心數增加而繼續擴展,那麼它很可能已經耗盡了全部可用的記憶體頻寬。繼續增加執行緒不會帶來收益,反而會讓延遲持續上升。STREAM 基準測試能提供節點層級的參考值,讓你可以把實測吞吐量與已知基線進行比較,而不是憑感覺判斷。因此,在正式排查之前,應先在 Linux 主機上執行該基準測試。

記憶體使用量與記憶體頻寬的差異

top 和 ps 這類工具回報的是記憶體使用量,也就是一個程序占用了多少記憶體,而不是它以多快的速度搬移資料。正因如此,在 Linux 上按程序統計頻寬始終是一個公認的監控難題。伺服器顯示較高的記憶體使用率,只能說明某個程序保留了較多頁面,並不能說明它正在高速移動資料。

你需要結合記憶體使用率、記憶體占用率以及 CPU 和記憶體使用情況一起觀察。一個記憶體占用很大的程序可能實際上處於閒置狀態,而另一個占用不大的程序卻可能在持續串流處理資料,並造成真正的記憶體壓力。應當把執行中的程序和伺服器程序放在系統記憶體容量的背景下進行分析,同時將 I/O 頻寬分開比較。僅靠伺服器記憶體使用量,無法回答真正的問題。在繁忙的伺服器上,應在業務高峰時對這些計數器取樣,而不是在閒置時取樣。這種區分可以避免伺服器效能分析得出錯誤結論。

Linux 工具清單與安裝

工具適用性與選擇

每一種工具回答的問題都不同,因此選擇工具時應看分析深度,而不是憑使用習慣。perf 能提供深入的單一程序計數器和硬體事件,因此當你必須把頻寬歸因到某個具體程序時,它是最有力的選擇。pidstat 提供輕量且快速的單一程序活動取樣,因此非常適合在繁忙伺服器上做第一輪排查。sar 能保留歷史資料,幫助你回溯到使用者抱怨前幾個小時的系統狀態。vmstat 則以簡潔的視圖提供系統層級的上下文。Intel PCM 還能補充硬體層面的細節,用於查看核心預設未直接暴露的計數器。

與之相鄰的其他工具則涵蓋不同環境。Intel VTune Profiler 的 Memory Usage View 能為單一應用程式建立時間軸,這在你需要分析程式碼而非排查整台主機時非常有幫助。PerfMon 則用於 Windows 上的資源使用追蹤,因此即使脫離 Linux,類似的調查也依然可行。應把這一整組工具視為 Linux 資源監控工具箱,而不是簡單的優先順序排名。

安裝指令

這些工具大多都可以透過標準軟體儲存庫安裝,而且通常需要 root 權限。在 OpenCloudOS 上,以 root 身分執行 yum install perf 和 yum install sysstat;其中 sysstat 套件提供 pidstat 和 sar。Debian 和 Ubuntu 使用者執行 apt install sysstat,而 CentOS、Rocky Linux、Fedora 和 RHEL 使用者執行 dnf install sysstat。安裝完成後,使用 systemctl start sysstat.service 啟動收集服務,否則 sar 將沒有任何歷史資料可供回顧。

vmstat 無需額外安裝,因為 procps-ng 套件已經包含它,你可以直接執行 vmstat。在開始取樣前,先檢查 perf_event_paranoid 設定;如果該值過於嚴格,就會阻止非特權使用者存取效能計數器,而 root 則可以避開這項限制。最好在故障發生之前確認每個二進位程式都能正常回應,而不是等到事故發生時才臨時驗證。

定位導致記憶體頻寬飽和的程序

使用 perf 和 pidstat 進行單一程序測量

先從工具鏈中最輕量的 pidstat 開始。以 root 身分執行 pidstat -r -p ALL 1 10,對所有執行中的程序進行取樣,每秒一次,共取樣十次。minflt/s 和 majflt/s 兩欄顯示頁面錯誤數;如果某個程序占用的資料並不多,卻持續保持穩定的缺頁速率,那麼它更可能表現為串流存取行為,而不是單純擁有一個很大的記憶體占用。若要更快地做初步排查,可以執行 pidstat -r 1 5 | sort -k7 -nr | head,優先列出記憶體占用超過 1GB 的程序。這樣你就能在不引入硬體計數器開銷的情況下取得即時記憶體統計資訊。

當你需要真正按吞吐量歸因時,再升級到 perf。對可疑程序執行 perf stat -e cycles,instructions,cache-misses -p <PID> sleep 10。如果快取未命中率很高,同時每週期指令數偏低,這通常意味著該程序正以超出快取供給能力的速度從 DRAM 拉取資料。若要查看系統整體情況,可以執行 perf stat -a -e cycles,instructions sleep 10,再將彙總結果與你的 STREAM 基線進行比較。像這樣細緻的程序分析,能夠把真正的頻寬吞噬者與僅僅占用大量頁面的程序區分開來。

借助 sar、vmstat 和 PCM 取得伺服器層級上下文

在深入某一個程序之前,先確認系統層面確實已經接近飽和。執行 sar -r 1 5 查看一段時間內的記憶體使用統計,重點關注 kbmemfree 和 kbmemused 所反映的壓力情況。然後執行 sar -B 1 5,檢查 pgscank/s 和 pgsteal/s。如果這些值持續上升,說明核心正在積極回收頁面,這是「某個程序導致記憶體頻寬飽和,進而拖累整台伺服器」的強烈訊號。

vmstat 則補充了一個簡潔的系統總覽。執行 vmstat 1 5,觀察 si 和 so 兩欄;如果在負載期間出現非零的 swap-in 和 swap-out,就表示伺服器確實存在記憶體壓力。Intel PCM 還能繼續深入。執行 pcm.x 1,讀取整合式記憶體控制器計數器,其中包括每個通道的每秒讀寫位元組數。將這一數值與 STREAM 參考值進行比較。如果讀數已經接近基線,就表示伺服器在硬體層面已經達到飽和,而不只是「比較繁忙」。

解讀這些欄位時一定要謹慎。由高到低排列的高記憶體使用量,只能告訴你誰持有最多頁面,而不能告訴你誰移動了最多位元組。一個擁有大型緩衝池的資料庫,可能表現出巨大的記憶體占用,但實際上處於閒置狀態;而一個較小的工作程序,可能透過持續串流讀寫資料來占滿記憶體匯流排。應按缺頁速率和快取未命中來排序活躍程序,而不是只按常駐記憶體大小排序。這種區分有助於保護你的伺服器效能結論不被誤導,讓排查保持嚴謹。

關聯驗證與預防

交叉核對日誌與指標

單次 perf 讀數可能會產生誤導,因此在採取措施前,應將可疑程序與系統日誌進行關聯。檢查 dmesg 和系統日誌,查看是否存在與取樣時間窗口一致的 OOM 殺程序、ECC 事件或頁面分配失敗。可以在 Linux 伺服器上執行 journalctl -k --since "1 hour ago" | grep -i memory,並將輸出時間戳與你測得的頻寬峰值對照起來。

接著,再將 sar 歷史與同一時間窗口交叉核對。在你的取樣中表現出高記憶體占用的程序,也應在那個小時的 sar 記錄中體現出一致趨勢。如果兩者不一致,就表示你的取樣捕捉到的可能只是一個瞬時突發,而不是持續模式。若條件允許,可在另一台負載相近的 Linux 主機上複核同樣的問題,再決定是否升級處理。這一步能夠把真正的元兇與偶然巧合區分開來。

持續監控建議

預防始於基線。記錄每台伺服器的 STREAM 測試結果和典型記憶體使用率,並在實測吞吐量接近該參考值時觸發警示。應定期取樣資源使用情況,而不是只在故障發生後才去查看。

  • 每小時執行一次 pidstat -r 1 60,並封存輸出結果。
  • 按週追蹤主要伺服器程序的記憶體使用趨勢。
  • 對 sar 中持續上升的 pgscank/s 設定警示,而不是只對記憶體占用率設定警示。

每次部署後都應重新檢查活躍的伺服器程序,因為新程式碼常常會改變頻寬使用模式。尤其要關注那些記憶體占用持續增長、但工作產出並未同步提升的執行中程序。

如今,AI 驅動的分析工具已經能夠預測記憶體飽和,並提出工作負載分配調整或硬體升級建議。但應把它們視為對直接測量的補充,而不是替代品。在 Linux 伺服器效能分析中,你自己採集到的計數器資料仍然是最終依據;當懷疑是某個程序導致記憶體頻寬飽和時,這些資料也能讓你的結論更有說服力。

首先對照 STREAM 基線確認是否真的發生了飽和。接著使用 pidstat 或 perf 將負載歸因到具體程序。然後用 sar 歷史和核心日誌驗證這一發現。最後建立定期取樣機制,讓下一次故障排查從資料開始,而不是從猜測開始。

建議準備一份簡短的故障處理清單:基線是否已記錄、是否已完成 pidstat 取樣、是否已讀取 perf 計數器、是否已比對 sar 時間窗口、是否已檢查日誌、是否已設定警示門檻。在任何 Linux 主機上,都建議先從 pidstat 開始,因為它開銷小、回饋快。只有在你需要硬體層級深度分析時,再升級到 perf 或 Intel PCM。這樣的順序能讓每一次伺服器排查都具備可重複性,也能把「模糊的系統變慢」轉化為「伺服器上某個已明確命名的程序」。

常見問題

應該先嘗試哪個工具?

先用 pidstat。它開銷小、見效快。在 Linux 主機上執行 pidstat -r -p ALL 1 10,重點查看缺頁相關欄位。只有在需要硬體層級深度分析時,再升級到 perf 或 Intel PCM。

如何判斷瓶頸是頻寬而不是 CPU?

先查看你的 STREAM 基線。出現頻寬飽和的伺服器通常表現為延遲升高,而 CPU 閒置率依然較高。同時,快取未命中率會上升,每週期指令數會下降。再結合 sar 歷史進行確認,然後再判斷是否應歸因於某個程序。

一個記憶體使用量很小的程序也會占滿匯流排嗎?

會。記憶體使用量和記憶體吞吐量是兩種完全不同的指標。一個占用不大的工作程序,完全可能因為持續串流搬移資料而占滿匯流排;而一個大型緩衝池則可能只是安靜地常駐在記憶體中。應按缺頁速率和快取未命中排序,而不是只看常駐記憶體大小。

在生產伺服器上應多久取樣一次?

應定期取樣,而不只是出問題時才取樣。建議每小時執行一次 pidstat -r 1 60 並封存結果;對 sar 中上升的 pgscank/s 設定警示。每次部署後都要重新檢查 Linux 伺服器,因為新程式碼可能會改變頻寬模式。

如果 STREAM 測試結果低於基線代表什麼?

較低的結果通常表示記憶體模組安裝不牢、通道未啟用,或記憶體批次混插。可以使用 ipmitool sel list | grep -i memory 進行確認。修復硬體問題後重新執行基準測試,並把修正後的結果作為該 Linux 伺服器的新參考值。