如果我們想知道,在一段時間內,那一個磁盤塊被讀寫的頻率最高,怎么辦?我問這個問題是看到taobao kernel wiki上面有這么一段話,看了我十分心癢:
通過對blktrace的輸出結果進行分析,我們可以對特定時間段內發生的讀、寫操作的磁盤塊進行I/O頻次統計。結合通過將磁盤塊I/O頻度統計和page cache命中率統計相結合,就可以比較有效的判斷服務器節點的cache使用效率。通過這套工具,CDN系統修正了一個固態硬盤上cache管理的缺陷,顯著提高了I/O性能(詳細信息)淘寶大神給了一個shell腳本解決這個問題,但是我守著代碼,不知道怎么用。就研究了下blktrace和大神的代碼。常常聽淘寶的霸爺,提起blktrace。iostat,iotop這些的工具也是統計磁盤IO的,也非常有用,但是和blktrace比,信息過于summarized,而blktrace跟蹤了發生在塊設備層的很多事件,簡直就是整個塊設備層事件的回放。blktrace能夠trace那些事件呢?
上面這個膠片來自HP的介紹blktrace的膠片,介紹的非常好,是參考文獻中一篇。 這些事件都會被blktrace 捕捉到。由于這些事件要和kernel代碼中block device的work flow一一對應,目前我的功力尚不足,所以我就不一一介紹這些事件了。 blktrace輸出的東西,不是文本,是一些特殊的格式,要想可讀,需要blkparse解析blktrace的輸出。 我們看下blktrace和blkparse合作方式
這是一個比較典型的使用: blktrace -d表示monitor哪個設備,-o -表示講輸出吐出到標準輸出。 blkparse -i - 表示從標準輸入獲取信息,-o 表示講解析的內容記錄在blkparse.out 我們看下輸出長的什么樣子:
這個膠片非常好的介紹了各個字段的含義。主次設備號,CPU ID,sequence num,time stamp PID ,起始扇區號,進程名字比較好理解,比較難理解的是$6,$7$6中的GPQMDC,一堆字母,代表什么含義?$7的WR 又代表什么含義呢? 一個一個來,對于$6,表示的是event,官方手冊給了事件對應表:
那么$7是干嘛的呢? 基本上是R和W,也會出現B和S. R表示是read操作,W表示write操作,B是barrier operation,S是synchronous operation。 看到這個blkparse的輸出,我們發現這些更像是raw data,需要我們挖掘背后的信息。btt這個工具就是一個分析輸出得到更高層信息的tool,他不是我們本文的重點,我們不提他。 回到開篇的問題,如何知道which磁盤扇區被讀寫的次數最多?有了blkparse的輸出,我們完全可以做到這個統計:淘寶的Coly大神的shell腳本已經幫我們作了這個事情。
root@manu-hacks:~/code/shell/blkstrace_calculator# cat cal.sh
#!/bin/bash
TMP_DIR=".blktrace_cal"
# extend the blktracelogto"blockid R/W"
extend()
{
awk-v max=$2-vmod=$3'{
if(NR%max==mod&&$6=="D"&&(index($7,"R")||index($7,"W"))){
for(i=0;i<$10;?i++)?{
print $8+i" "substr($7,1,1);
}
}
}'$1|sort-k1-nr>$TMP_DIR/.tmp.$1.$3
touch $TMP_DIR/$3.ok
}
usage()
{
echo"Usage: $1 input_log [parallel_num]"
exit
}
rm-rf $TMP_DIR
mkdir $TMP_DIR
if["$1"==""];then
usage $0
fi
# does input_log exists?
if[!-f $1];then
echo"($1) not exists"
exit
fi
parallel=$2
if["$2"==""];then
parallel=4
fi
echo"[input: $1]"
max=`expr $parallel-1`
files=""
filename=`basename $1`
echo"[run $parallel process]"
foriin`seq 0 $max`
do
extend $filename $parallel $i&
files=$files" $TMP_DIR/.tmp.$filename.$i"
done
echo"processing...."
nr=0
# awk will finishifall*.ok created.
while[$nr-ne"$parallel"]
do
nr=`find $TMP_DIR-maxdepth 1-name"*.ok"|wc-l`
echo-n"."
sleep 1
done
echo""
echo"merge sort"
sort-m-k1-nr $files|uniq-c|sort-k1-nr>tmp
total=`awk'{sum+=$1}END{print sum}'tmp`
awk-v sum=$total'{
print $0"\t"$1*1000/sum;
}'tmp>result
echo"sort finish."
rm-rf $TMP_DIR
這段代碼是Coly大神的代碼,我無意抄襲前輩,只是晚輩拿來欣賞學習,光榮屬于淘寶的Coly前輩。 先說parallel,這個是為了充分利用CPU資源,讓多個CPU一起來執行extend。NR%max==mod將一個文件按照行分開,由多個進程分別處理之。不多講。 extend的含義也比較簡單:
20397704是起始扇區,+ 8表示的連續8個扇區都在本次事件之內,也就是說20397704/20397705/20397706..都是本次事件涉及的扇區。 OK,我們看下cal.sh的使用及輸出:
當前目錄下生成了tmp和result文件:
我們可以看到,扇區號為454375583被訪問的次數為39次,占總訪問的千分之0.228744。那這個扇區屬于拿個文件呢?debugfs就可以來幫忙了.我們以訪問27次的264753359扇區為例。扇區是512字節,我的文件系統ext4的塊大小是4K,所以根據扇區可以定位的塊號,debugfs根據塊號,可以定位到inode,再根據inode,就可定位到filename。
我們發現,這個文件被讀寫的次數最多。誰干的? lsof來幫忙?
我們用Coly大神的腳本和blktrace/blkparse就解決了磁盤塊IO訪問頻率的統計。如果有個別的block被頻繁的讀取,表示cache的替換效率不高。
-
磁盤
+關注
關注
1文章
379瀏覽量
25230 -
固態硬盤
+關注
關注
12文章
1468瀏覽量
57453
原文標題:使用blktrace統計磁盤塊I/O訪問頻率
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論