FIO詳解

fio - Flexible IO Tester

一、服務器配置:

由於我們想通過fio得到SSD真實的參數信息,因此我們需要服務器BIOS一些參數的配合,以便能更好的體現硬盤的性能。
在這裏插入圖片描述
以華爲1288HV5爲例:
在這裏插入圖片描述

二、fio

1.安裝

a.下載地址:http://freshmeat.sourceforge.net/projects/fio/
b.安裝兩個插件
#yum install libaio*
#yum install zilb*
c.編譯安裝
#tar -xvf fio-2.1.10.tar.gz
#cd fio-2.1.10
#./configure
#make
#make install

2.fio執行腳本順序

1)Secure erase the drive
2)Prefill the drive with Sequential Write (128K Sequential Write QD=32 / size=100% with loops=2 / numjobs=1)
3)128K 100% Sequential Write (ramp_time=60sec / runtime=2h / QD=32 / numjobs=1)
4)128K 100% Sequential Read (ramp_time=60sec / runtime=2h / QD=32 / numjobs=1)

5)Prefill the drive with randwrite (128K randwrite QD=32 / runtime=3hr / numjobs=1)
6) 4K 100% Random Write (ramp_time=60sec / runtime=2h / QD=32 / numjobs=1)
7)4K 100% Random Read (ramp_time=60sec / runtime=2h / QD=32 / numjobs=1)

注意事項:
a.硬盤應直連主板這樣測出來的數據更加真實,但如SATA通過Raid Card連接應將硬盤設置爲JBOD。
b.硬盤測試前一定要進行安全擦除。
c.順序讀、順序寫前可以不添加穩態處理。
d.隨機讀、隨機寫前一定要有randwrite 2h(這個時間與硬盤容量大小有關,4T以下設置2個小時應該沒有問題)左右的穩態處理,如果沒有添加會影響Random write。下圖就是在隨機讀寫前未加穩態處理時,rand_write iops的圖
在這裏插入圖片描述
e.測試時間runime的值應儘量不低於1h,如果時間很短沒有測試實際意義。

3.執行腳本,以SATA接口硬盤爲例:

./SATA.sh sdb

#**************************Script of precondition*************************#
echo "$DEV precondition seq write ready"
date
fio --ioengine=libaio --direct=1 --thread --norandommap --filename=/dev/"$DEV" --name="$DEV"_init_seq --output="$DEV"_init_seq.log --rw=write --bs=128k --numjobs=1 --iodepth=128 --loops=2

#**************************Script of seq*************************#
for WL2 in write read
do
	for jobs2 in 1
	do
		for QD2 in 128
		do
			for runt2 in 1800
			do
				for block2 in 128k
				do

echo "$DEV rw_${WL2}  bs_${block2} nujobs_${jobs2} QD_${QD2} test      "
date
issdcm -drive_index 0 -smart >"$DEV"_${block2}_${WL2}_${jobs2}_${QD2}_smart.log
fio --ioengine=libaio --randrepeat=0 --norandommap --thread --direct=1 --group_reporting --name=mytest --ramp_time=60 --runtime=${runt2} --time_based --numjobs=${jobs2} --iodepth=${QD2} --filename=/dev/"$DEV" --rw=${WL2} --bs=${block2} --output="$DEV"_${block2}_${WL2}_${jobs2}_${QD2}.log --log_avg_msec=1000 --write_iops_log="$DEV"_${block2}_${WL2}_${jobs2}_${QD2}_iops --write_lat_log="$DEV"_${block2}_${WL2}_${jobs2}_${QD2}_lat --write_bw_log="$DEV"_${block2}_${WL2}_${jobs2}_${QD2}_bw
				done
			done
		done
	done
done
#**************************Script of precondition*************************#
echo "$DEV precondition random write ready"
date
fio --ioengine=libaio --direct=1 --thread --norandommap --filename=/dev/"$DEV" --name="$DEV"_init_random --output="$DEV"_init2_random.log --rw=randwrite --bs=128k --numjobs=4 --iodepth=64 --time_based --ramp_time=60 --runtime=7200
#**************************Script of random*************************#
for WL in randwrite randread
do
	for jobs in 4
	do
		for QD in 64
		do
			for runt in 1800
			do
				for block in 8k 4k
				do	
			
echo "$DEV rw_${WL} bs_${block} nujobs_${jobs} QD_${QD} test    "
date
issdcm -drive_index 0 -smart >"$DEV"_${block}_${WL}_${jobs}_${QD}_smart.log
fio --ioengine=libaio --randrepeat=0 --norandommap --thread --direct=1 --group_reporting --name=mytest --ramp_time=60 --runtime=${runt} --time_based --numjobs=${jobs} --iodepth=${QD} --filename=/dev/"$DEV" --rw=${WL} --bs=${block} --output="$DEV"_${block}_${WL}_${jobs}_${QD}.log --log_avg_msec=1000 --write_iops_log="$DEV"_${block}_${WL}_${jobs}_${QD}_iops --write_lat_log="$DEV"_${block}_${WL}_${jobs}_${QD}_lat
				done
			done
		done
	done
done

#**************************Script of randrw*************************#
for WL1 in randrw
do
	for jobs1 in 4
	do
		for QD1 in 64
		do
			for runt1 in 1800
			do
				for block1 in 8k 4k
				do	
			
echo "$DEV rw_${WL1}  bs_${block1} nujobs_${jobs1} QD_${QD1} test    "
date
issdcm -drive_index 0 -smart >"$DEV"_${block1}_${WL1}_${jobs1}_${QD1}_smart.log
fio --ioengine=libaio --randrepeat=0 --norandommap --thread --direct=1 --group_reporting --name=mytest --ramp_time=60 --runtime=${runt1} --time_based --numjobs=${jobs1} --iodepth=${QD1} --filename=/dev/"$DEV" --rw=${WL1} --rwmixread=70 --bs=${block1} --output="$DEV"_${block1}_${WL1}_${jobs1}_${QD1}.log --log_avg_msec=1000 --write_iops_log="$DEV"_${block1}_${WL1}_${jobs1}_${QD1}_iops --write_lat_log="$DEV"_${block1}_${WL1}_${jobs1}_${QD1}_lat
				done
			done
		done
	done
done

4.數據分析

順序讀、順序寫主要看BW,隨機讀、隨機寫主要看IOPS.
1)怎麼看lat分佈?

bw (KB  /s): min=   71, max=  251, per=0.36%, avg=154.84, stdev=18.29

    lat (usec) :   2= 0.01%,   4=0.01%,  10=0.01%,   20=0.01%, 50=51.41%
    lat (usec) : 100=48.53%, 250=0.06%, 500=0.01%, 1000=0.01%
    lat (msec) :   2= 0.01%,   4=0.01%,  10=0.01%,   20=0.01%

這組數據表示latency的分佈,說明了51.41%的request延遲小於50微秒,48.53%的延遲小於100微秒(但是大於50微秒),以此類推
其他待續:
參考:https://blog.csdn.net/feilianbb/article/details/50497845

2)fio log收集
請參考<利用Python3.4+收集fio測試結果>
https://blog.csdn.net/weixin_40343504/article/details/97886537

5.fio常用參數詳解

a.loops=int
重複運行某個job多次,默認是1。
loops與runtime是兩個不能同時存在的兩個參數,loops主要是定義硬盤執行的圈數,而runtime只是定義fio執行的時間。
b.time_based
如果設置的話,即使file已被完全讀寫或寫完,也要執行完runtime規定的時間。它是通過循環執行相同的負載來實現的,與runtime相對應。
c.ramp_time=time
設定在記錄任何性能信息之前要運行特定負載的時間。這個用來等性能穩定後,再記錄日誌結果,因此可以減少生成穩定的結果需要的運行時間。
d.randrepeat=bool
對於隨機IO負載,配置生成器的種子,使得路徑是可以預估的,使得每次重複執行生成的序列是一樣的。

如果無–randrepeat=0這個參數不會影響seqread,但會影響seqwrite,randwrite,randread.

在這裏插入圖片描述
e.norandommap
一般情況下,fio在做隨機IO時,將會覆蓋文件的每一個block.如果這個選項設置的話,fio將只是獲取一個新的隨機offset,而不會查詢過去的歷史。這意味着一些塊可能沒有讀或寫,一些塊可能要讀/寫很多次。在個選項與verify=互斥,並只有多個塊大小(bsrange=)正在使用,因爲fio只會記錄完整的塊的重寫。
f.thread
fio默認會使用fork()創建job,如果這個選項設置的話,fio將使用pthread_create來創建線程。
在這裏插入圖片描述
g.direct=bool
direct=1 測試過程繞過機器自帶的buffer。使測試結果更真實。
h.group_reporting
如果‘numjobs’設置的話,我們感興趣的可能是打印group的統計值,而不是一個單獨的job。這在‘numjobs’的值很大時,一般是設置爲true的,可以減少輸出的信息量。如果‘group_reporting’設置的話,fio將會顯示最終的per-groupreport而不是每一個job都會顯示。
i.numjobs=int
創建特定數目的job副本。可能是創建大量的線程/進程來執行同一件事。我們將這樣一系列的job,看作一個特定的group。

參考:https://www.itzhoulin.com/2015/12/24/fio-man-guide/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章