詳解Linux下的IO監(jiān)控與分析:系統(tǒng)級+進程級+業(yè)務級+文件級IO
概述
學習優(yōu)化,理解IO還是很重要的,今天抽空整理了一下這塊內(nèi)容,下面一起看看吧~
下面這張經(jīng)典的圖源自 Linux Performance and Tuning Guidelines.pdf

各種IO監(jiān)視工具在Linux IO 體系結(jié)構(gòu)中的位置
1 、系統(tǒng)級IO監(jiān)控
1.1、iostat
- iostat -xdm 1 # 個人習慣
%util 代表磁盤繁忙程度。100% 表示磁盤繁忙, 0%表示磁盤空閑。但是注意,磁盤繁忙不代表磁盤(帶寬)利用率高
argrq-sz 提交給驅(qū)動層的IO請求大小,一般不小于4K,不大于max(readahead_kb, max_sectors_kb)
可用于判斷當前的IO模式,一般情況下,尤其是磁盤繁忙時, 越大代表順序,越小代表隨機
svctm 一次IO請求的服務時間,對于單塊盤,完全隨機讀時,基本在7ms左右,既尋道+旋轉(zhuǎn)延遲時間
1.2、各統(tǒng)計量之間關(guān)系
%util = ( r/s + w/s) * svctm / 1000 # 隊列長度 = 到達率 * 平均服務時間
avgrq-sz = ( rMB/s + wMB/s) * 2048 / (r/s + w/s) # 2048 為 1M / 512
1.3、總結(jié)
iostat 統(tǒng)計的是通用塊層經(jīng)過合并(rrqm/s, wrqm/s)后,直接向設(shè)備提交的IO數(shù)據(jù),可以反映系統(tǒng)整體的IO狀況,但是有以下2個缺點:
- 距離業(yè)務層比較遙遠,跟代碼中的write,read不對應(由于系統(tǒng)預讀 + pagecache + IO調(diào)度算法等因素, 也很難對應)
- 是系統(tǒng)級,沒辦法精確到進程,比如只能告訴你現(xiàn)在磁盤很忙,但是沒辦法告訴你是誰在忙,在忙什么?
2 、進程級IO監(jiān)控
2.1、 iotop 和 pidstat (僅rhel6u系列)
iotop 顧名思義, io版的top
pidstat 顧名思義, 統(tǒng)計進程(pid)的stat,進程的stat自然包括進程的IO狀況
這兩個命令,都可以按進程統(tǒng)計IO狀況,因此可以知道:
1)當前系統(tǒng)哪些進程在占用IO,百分比是多少?
2)占用IO的進程是在讀?還是在寫?讀寫量是多少?
pidstat 參數(shù)很多,介紹幾個比較常用的:
- pidstat -d 1 #只顯示IO
- pidstat -u -r -d -t 1
- # -d IO 信息,
- # -r 缺頁及內(nèi)存信息
- # -u CPU使用率
- # -t 以線程為統(tǒng)計單位
- # 1 1秒統(tǒng)計一次
- iotop, 很簡單,直接敲命令
2.2、block_dump, iodump
iotop 和 pidstat 都依賴于/proc/pid/io文件導出的統(tǒng)計信息, 這個對于老一些的內(nèi)核是沒有的,比如rhel5u2。
因此只好用以上2個命令來替代:
- echo 1 > /proc/sys/vm/block_dump # 開啟block_dump,此時會把io信息輸入到dmesg中
# dmesg
- watch -n 1 "dmesg -c | grep -oP "w+(d+): (WRITE|READ)" | sort | uniq -c"
# 不停的dmesg -c
- echo 0 > /proc/sys/vm/block_dump # 不用時關(guān)閉
2.3、總結(jié)
從進程級IO監(jiān)控 ,可以看出:
- 系統(tǒng)級IO監(jiān)控不能回答的2個問題
- 距離業(yè)務層相對較近(例如,可以統(tǒng)計進程的讀寫量)
但是也沒有辦法跟業(yè)務層的read,write聯(lián)系在一起,同時顆粒度較粗,沒有辦法知道當前進程讀寫了哪些文件? 耗時? 大小 ?
3、 業(yè)務級IO監(jiān)控
3.1、ioprofile
ioprofile 命令本質(zhì)上是 lsof + strace,
ioprofile 可以解決以下三個問題:
- 當前進程某時間內(nèi),在業(yè)務層面讀寫了哪些文件(read, write)?
- 讀寫次數(shù)是多少?(read, write的調(diào)用次數(shù))
- 讀寫數(shù)據(jù)量多少?(read, write的byte數(shù))
3.2、實例
假設(shè)某個行為會觸發(fā)程序一次IO動作,例如: "一個頁面點擊,導致后臺讀取A,B,C文件"
./io_event # 假設(shè)模擬一次IO行為,讀取A文件一次, B文件500次, C文件500次
ioprofile -p `pidof io_event` -c count # 讀寫次數(shù)
ioprofile -p `pidof io_event` -c times # 讀寫耗時
ioprofile -p `pidof io_event` -c sizes # 讀寫大小
注: ioprofile 僅支持多線程程序,對單線程程序不支持. 對于單線程程序的IO業(yè)務級分析,strace足以。
3.3、總結(jié)
ioprofile本質(zhì)上是strace,因此可以看到read,write的調(diào)用軌跡,可以做業(yè)務層的io分析。
4 、文件級IO監(jiān)控
文件級IO監(jiān)控可以配合/補充"業(yè)務級和進程級"IO分析
文件級IO分析,主要針對單個文件, 查看當前哪些進程正在對某個文件進行讀寫操作.
- lsof 或者 ls /proc/pid/fd
- inodewatch.stp
4.1、lsof
查看當前文件由哪些進程打開
lsof ../io # io目錄 當前由 bash 和 lsof 兩個進程打開
lsof 命令 只能查看靜態(tài)的信息, 并且"打開" 并不一定"讀取", 對于 cat ,echo這樣的命令, 打開和讀取都是瞬間的,lsof很難捕捉
4.2、inodewatch.stp
可以用 inodewatch.stp 來彌補
- stap inodewatch.stp major minor inode # 主設(shè)備號, 輔設(shè)備號, 文件inode節(jié)點號
- stap inodewatch.stp 0xfd 0x00 523170 # 主設(shè)備號, 輔設(shè)備號, inode號,可以通過 stat 命令獲得