iostat 與 iotop:診斷 Linux 儲存瓶頸

14 分鐘閱讀 - 2026年6月12日

hero section cover
目錄
  • iostat 與 iotop:診斷 Linux 儲存瓶頸
  • 安裝 iostat 與 iotop
  • 閱讀 iostat 輸出
  • 解讀 iotop 輸出
  • 診斷工作流程
  • 解決常見的 I/O 瓶頸
分享

使用 iostat 和 iotop 來尋找 Linux 磁碟 I/O 瓶頸。涵蓋 NVMe 上的 %util gotcha、讀取等待與佇列深度,以及找出並修復它的工作流程。

iostat 與 iotop:診斷 Linux 儲存瓶頸

當 Linux 伺服器運作緩慢時,儲存系統是首要檢查的對象之一。iostat 可顯示磁碟是否過載;iotop 則能指出造成負載的程序。兩者結合使用,便能解答兩個關鍵問題:磁碟是否確實是瓶頸?若是,究竟是什麼在造成過度負載? 本文涵蓋安裝步驟、如何解讀輸出結果(包括 iostat 的 %util 指標在現代硬體上的位置),以及從症狀到解決的完整工作流程。

安裝 iostat 與 iotop

iostat 隨 sysstat 套件一併提供;iotop 則需單獨安裝。請安裝兩者:

# Debian/Ubuntu
sudo apt install sysstat iotop
 
# RHEL, AlmaLinux, Rocky, CentOS Stream
sudo dnf install sysstat iotop
 
# Arch
sudo pacman -S sysstat iotop

在 Ubuntu 系統中,sysstat 預設為停用狀態。若要收集背景資料以便日後透過 sar,請編輯 /etc/default/sysstat,將 ENABLED="true",並重新啟動服務:

sudo systemctl restart sysstat

iotop 必須以 root 身分執行。在 RHEL 9 及更新版本中,延遲計量功能預設為停用狀態,這會導致 IOSWAPIN 欄位將呈現空白。請使用以下指令啟用:

echo 1 | sudo tee /proc/sys/kernel/task_delayacct

新增 kernel.task_delayacct = 1/etc/sysctl.conf 中,使其在重新開機後仍能生效。

閱讀 iostat 輸出

以擴展統計模式執行 iostat,並忽略第一個樣本(該樣本僅顯示自開機以來的平均值):

iostat -xz 2

使用 -x 標誌會新增延伸統計資料, -z 隱藏閒置裝置,且 2 每兩秒刷新一次。重要的欄位:

  • await:I/O 請求完成所需的平均時間(以毫秒為單位),包含佇列等待時間。當使用者抱怨系統遲緩時,這是最重要的單一數值。
  • r/s 以及 w/s:讀寫 IOPS。結合 rkB/s 以及 wkB/s 這些數據,可判斷您的工作負載屬於隨機型(高 IOPS、低吞吐量)或序列型(低 IOPS、高吞吐量)。
  • aqu-sz:平均佇列深度。對於 HDD 而言,若持續高於 1,表示磁碟無法跟上處理速度。
  • %util:裝置處於至少有一個 I/O 正在處理中的時間百分比。對 HDD 有用,但對 NVMe 可能產生誤導(見下文)。

快速閾值參考:

磁碟類型關注事項queue-depth 關注點%util 是否可靠?
7200 RPM 硬碟> 20 毫秒> 1
SATA SSD> 10 毫秒> 4多數情況下
NVMe> 1-2 毫秒> 16

%util 所在之處

%util 是多數人首先關注的指標,但在 NVMe 上這會造成嚴重誤導。核心將 %util 「任何時刻正在進行中的 I/O」,這對一次處理單一請求的機械硬碟來說尚可,但對於透過硬體佇列並行處理數千個請求的 NVMe 裝置而言則毫無意義。一顆 NVMe 硬碟可能顯示 100% %util ,實際使用率卻僅有 5%。

在 NVMe 上,請相信 r_await, w_awaitaqu-sz 。若 r_await 保持在 1 毫秒以下,且佇列深度遠低於裝置的硬體佇列深度(通常為 1024 或更高),那麼無論 %util 顯示的數值為何,該磁碟實際上並未達到飽和。

若要以 MB/s 而非 kB/s 檢視高速 NVMe 效能:

iostat -xm 1

若需長期收集資料,日後可與應用程式日誌進行關聯分析:

iostat -x -t 5 720 > /var/log/iostat.log

這會每 5 秒採樣一次,持續一小時。 sar 來自同一 sysstat 套件的

透過 CPU iowait 進行確認

若 iostat 顯示儲存裝置負載過高,請與 %iowait 同一輸出頂端 CPU 摘要中的 iowait 欄位進行交叉比對。若 iowait 值持續 %iowait 持續高於 15-20%,加上 await 則可確認瓶頸在於儲存裝置。若 %iowait 值偏高但 await 卻看似正常,請執行 vmstat 1 並檢查 siso 欄位。若存在非零的交換活動,表示系統受記憶體限制,且磁碟流量源於分頁操作,而非應用程式 I/O。

解讀 iotop 輸出

一旦 iostat 確認存在儲存瓶頸,iotop 會告訴您是哪個程序造成的。請從以下命令開始:

sudo iotop -o

-o 參數會隱藏閒置進程,僅保留正在進行 I/O 操作的進程。需關注的欄位:

  • DISK READ / DISK WRITE:每個進程的即時吞吐量。可識別明顯的 I/O 消耗大戶。
  • IO:進程因 I/O 而阻塞的時間百分比。即使某進程僅以 50 kB/s 的速度寫入資料,若其執行的是微小的同步 fsync() 呼叫。此欄位比原始吞吐量更為重要。
  • SWAPIN:等待交換頁面的時間百分比。此處若非零,表示系統正在進行分頁,而您的「儲存空間問題」實則為記憶體問題。

對於多執行緒應用程式(MySQL、PostgreSQL、Java 工作負載),請使用 -P,並加上 -a 以累積自 iotop 啟動以來的總和:

sudo iotop -oPa

使用 -a 參數是捕捉突發性工作負載的關鍵,例如每次僅運行數秒的備份任務,否則在即時檢視中將難以察覺。

若要在夜間無人監控的時段進行無人值守的記錄:

sudo iotop -botqq -d 10 > /var/log/iotop.log

這會每 10 秒寫入一個非互動式快照。將其與備份或 cron 任務的時間戳記搭配使用,即可在事後找出肇因。

診斷工作流程

大多數磁碟 I/O 調查都遵循相同的步驟:

  1. iostat -xz 2 確認磁碟是否確實是瓶頸。檢視 await, aqu-sz,以及 %iowait。若這些數值正常,問題便不在儲存裝置,您應將調查範圍轉向其他地方。
  2. iotop -oPa 找出驅動負載的程序。請多關注 I/O 欄位,而非吞吐量欄位。最嚴重的肇因通常是執行大量小型同步寫入的程式,而非傳輸最多位元的程式。
  3. lsof -p <pid> 確認該程序正在存取哪些檔案。這通常能立即辨識工作負載的類型:資料庫預寫日誌、應用程式日誌檔、備份掛載點,或是暫存檔。

有兩種模式值得了解。

若您看到類似 jbd2/... (ext4 日誌) 或 txg_sync (ZFS) 這類核心執行緒,它們只是在回應其他進程的寫入請求,而非主動發起寫入。真正導致日誌流量的用戶空間進程才是實際肇因;請繼續深入追查。

在 VPS 上, await 且低 %util 是典型的「吵鬧鄰居」徵兆。這表示另一位租戶正壟斷共享儲存空間,導致您的 I/O 排隊發生在超管理程式層面,而非您的虛擬磁碟上。您雖可在虛擬機器內部確認此狀況,但無法從中解決;解決方案是向服務供應商反映問題,或是遷移至配備獨立儲存空間的伺服器。

解決常見的 I/O 瓶頸

一旦了解是哪些因素在影響磁碟效能,解決方案通常相當直接。

降低非關鍵 I/O 的優先級。 ionice 將程序移至閒置調度類別,使其僅在無其他程序需求時才使用磁碟頻寬:

ionice -c 3 -p <pid>
sudo ionice -c 3 rsync -a /data /backup

第一種形式用於變更正在執行的程序;第二種則會啟動一個預先歸類於閒置類別的新程序。在 iotop 中,您可以透過按下 i 鍵,以互動方式變更正在執行的程序之優先級。

將熱工作負載移至更快的儲存裝置。若 iostat 顯示 SATA 磁碟因資料庫寫入而過載,且同一台伺服器內有閒置的 NVMe 裝置,請將資料庫資料目錄遷移至該裝置。由於 IOPS 效能相差數個數量級,這將是當前最具效益的解決方案。

設定正確的 I/O 排程器。現代核心的預設值通常合理,但仍值得檢查。對於 NVMe 和 SSD,請將排程器設定為 none。該裝置在硬體層面的佇列處理能力遠勝於核心:

echo none > /sys/block/nvme0n1/queue/scheduler

對於處理混合工作負載的 HDD, mq-deadline 通常是首選。

使用 noatime 掛載。預設情況下,每次讀取都會更新檔案的最後存取時間戳記,導致每次讀取都會產生寫入操作。在以讀取為主的檔案系統中,這屬於不必要的 I/O。請將 noatime 至掛載選項中 /etc/fstab:

UUID=... /data ext4 defaults,noatime 0 2

針對突發性寫入調整寫回機制。在具備充足記憶體的伺服器上,預設的髒頁閾值會讓頁面快取累積數GB的未寫入資料,隨後才一次性大量沖洗。請降低 /etc/sysctl.conf 中的閾值以平滑此現象:

vm.dirty_ratio = 10
vm.dirty_background_ratio = 5

磁碟本身通常不是問題。當 iostat 顯示高 IOPS 且低吞吐量時,表示工作負載正在對本可順序讀寫的資料進行隨機 I/O,或是執行許多本可批次處理的小型寫入操作。在歸咎硬體之前,請先檢視應用程式。

若您在網路效能可能超越磁碟的伺服器上執行儲存密集型工作負載,FDC 搭載 NVMe 的專用伺服器將提供充足的效能餘裕,讓您能有效運用上述調校技巧。

博客

本周特色

更多文章
Linux 伺服器工作負載最佳化的調校設定檔

Linux 伺服器工作負載最佳化的調校設定檔

如何為 GPU、資料庫和高頻寬 Linux 伺服器選擇、應用和客製化已調整的配置文件,並提供範例和 Ansible 部署技巧。

16 分鐘閱讀 - 2026年6月9日

Linux OOM Killer Tuning for VPS:實用指南

12 分鐘閱讀 - 2026年6月8日

更多文章