針對IO密集型應用做系統調優的時候,我們通常都需要知道系統cpu 內存 io 網絡等系統性能 和 使用率,結合應用本身的訪問量,以及 mysql的性能指標來綜合分析。比如說:我們將系統壓力情況分為三個階段:從用戶端開始到web server,再到mysql。
1. 客戶量:我們可以從web app的訪問log,查看訪問量(通常會記錄時間),
2. 系統指標: 對比dstat、 iostat/ mpstat pidstat 等搜集對應的系統性能指標,
3. mysql: 使用mysql status ,或者 mycheckpoint等工具搜集mysql的cache , query等數據。
但是問題來了,我們很容易搜集到了系統層、設備層的IO數據,但是缺少一個體貼的工具來告訴你應用打開了多少文件,文件讀寫比例,執行了多少次fsync,是隨機讀寫還是順序讀寫,另外,mysql是一個龐大而精心設計的系統,使用了一些列的方案如table cache, thread cache 等來提升IO,我們比較容易獲得他的緩存量,命中率,文件數,但是卻不好直觀的知道它到底對物理IO設備讀寫了多少數據。
ioprofile就是這樣一個工具,提供了直觀的量化的數據來描述進程對io設備的真實讀寫量。
由於實現方式是使用strace注入到線程中,所以運行時需要sudo,方法如下:
sudo ./pt-ioprofile -p 8534 -c count
sudo ./pt-ioprofile -p 8534 -c sizes
2015年 04月 23日 星期四 17:55:35 CST Tracing process ID 8534 total read pwrite fsync open close filename 613878 613878 0 0 0 0 /redmine/mysql/data/mycheckpoint/sv_diff.frm 406924 406924 0 0 0 0 /redmine/mysql/data/mycheckpoint/sv_sample.frm 18432 0 18432 0 0 0 /redmine/mysql/data/ib_logfile1 3029 3029 0 0 0 0 /redmine/mysql/data/mycheckpoint/custom_query_view.frm
sudo ./pt-ioprofile -p 8534 -c times
2015年 04月 23日 星期四 17:54:09 CST Tracing process ID 8534 total pwrite fsync filename 0.100162 0.000271 0.099891 /redmine/mysql/data/ibdata1 0.003826 0.000000 0.003826 /redmine/mysql/data/ib_logfile0
sudo ./pt-ioprofile -p 8534 -c sizes -g filename
有人在生產環境中使用ioprofile時出現導致mysql掛起的現象,雖然是4年前了,但還是請謹慎使用。
以上數據輸出中的 read write fread fwrite fsync 等指標分別是指什么呢? 多大的量才算正常?
read/write/fsync:
1. linux底層操作;
2. 內核調用, 涉及到進程上下文的切換,即用戶態到核心態的轉換,這是個比較消耗性能的操作。
fread/fwrite/fflush:
1. c語言標准規定的io流操作,建立在read/write/fsync之上
2. 在用戶層, 又增加了一層緩沖機制,用於減少內核調用次數,但是增加了一次內存拷貝。
關系參看下圖:

1. 對於輸入設備,調用fsync/fflush將清空相應的緩沖區,其內數據將被丟棄;
2. 對於輸出設備或磁盤文件,fflush只能保證數據到達內核緩沖區,並不能保證數據到達物理設備, 因此應該在調用fflush后,調用fsync(fileno(stream)),確保數據存入磁盤。
參考:
1. http://blog.yufeng.info/archives/995
2. http://blog.csdn.net/ybxuwei/article/details/22727565
