
我正在嘗試測量正在運行的進程的磁碟 IO 延遲以製作直方圖。
我可以在提供它的作業系統中使用 DTrace 來做到這一點(例如,這篇 Joyent 論文),但我的應用程式在 Linux 中運行。我的第一個想法是嘗試perf
,我可以得到計數器,但我找不到任何方法來獲取時間增量。我可以使用strace
(例如)獲得時間增量strace -e read -T
,但我不確定是否可以將追蹤限制為磁碟IO(該系統也有一個繁忙的網路介面)。
在Linux下有什麼辦法可以做到這一點嗎?
答案1
這其實很複雜。但有提示:
了解 SystemTap,這是 DTrace 的 Linux 模擬。我認為他們甚至可能有類似任務的範例腳本。
學習區塊追蹤。理論上,您也許能夠解析它的輸出。這將比設備延遲(服務時間)更長回應時間節目上車
read()
。
是strace
可能不合適,因為它會追蹤所有內容(所有系統調用,即使您使用-e
過濾器)並且會加載伺服器並顯著減慢進程。Perf
是一個非常晦澀的工具,您可能有時會認為自己理解了它的輸出,但實際上並沒有,而且它的功能集高度依賴於內核版本。基本上目前perf
適合測量中央處理器時間(週期),且[但]不適合測量回應時間(你實際上需要的)。我聽說他們想要實現一些東西來緩解這個問題,所以在最近開發的核心上可能會有一些東西。 (perf script -l
如果您想進一步調查,您也可以查看 perf-scripts ( )。)
也許你能從中得到一些東西追蹤。閱讀這篇文章http://lwn.net/Articles/370423/(這對於介紹.) 正如我所看到的,您可以透過
pid
和 函數來限制 ftracing,然後使用類似sys_read
.我試過這個作為例子給你:# mount -t debugfs debugfs /sys/kernel/debug # if it's not already mounted # cd /sys/kernel/debug/tracing # echo $$ > set_ftrace_pid # pid of process to trace # echo sys_read sys_write > set_ftrace_filter # echo function_graph > current_tracer # head trace # tracer: function_graph # # CPU DURATION FUNCTION CALLS # | | | | | | | 0) 8.235 us | sys_write(); 0) 3.393 us | sys_write(); 0) ! 459859.3 us | sys_read(); 0) 6.289 us | sys_write(); 0) 8.773 us | sys_write(); 0) ! 1576469 us | sys_read();
答案2
如果您只對區塊裝置的「讀取」或「寫入」呼叫數量感興趣這是紅帽的 SOP,用於確定。
使用區塊轉儲功能和一些腳本,可以收集有關正在產生的 I/O 操作流程的高階概述。為此,請完成以下操作:
短時間內停用系統日誌記錄(這樣就不會妨礙資料擷取):
# 服務 syslog 停止 # echo 1 > /proc/sys/vm/block_dump
等待高 iowait 問題發生,一旦重新啟用 syslog(或 rsyslog,如果使用它),並停用區塊轉儲:
# 服務系統日誌啟動 # echo 0 > /proc/sys/vm/block_dump
使用以下命令解析 dmesg 輸出以尋找某些進程發出的讀取/寫入/髒操作:
# dmesg | awk '/(READ|WRITE|dirtied)/ {activity[$1]++} END {for (x in Activity) print x, Activity[x]}'|排序-nr -k 2,2|頭 -n 10
kjournald(1425): 5984 kjournald(3681): 1269 pdflush(27301): 725 iostat(2913): 134 crond(26919): 61 crond(28985): 60685 5388 ): 50 鸚鵡螺(24498): 46
上面的範例輸出顯示了在區塊轉儲運作期間發出 READ、WRITE 和髒操作的前 10 個進程。使用此資料可以收集正在發出的操作進程數量的高級概述,並且可以幫助確定單一進程是否對 iowait 貢獻很大。
還有一些命令列工具,例如atop 和iotop,可以為您提供每個進程的iowait 統計信息,並且可以作為腳本的一部分運行(這意味著它們具有批處理模式,可以對特定PID 進行單次迭代) 。
編輯: 做更多研究看起來你可以從 /proc/$pid/stat 取得每個行程的 iowait(搜尋「聚合區塊 I/O 延遲」)