fio:Flexible IO Tester
1、安裝
yum install libaio-devel # 安裝異步io引擎
tar xzvf fio-2.1.10.tar.gz
cd fio-2.1.10/
./configure
make
make install
2、使用參數說明
filename=/data/file 測試文件名稱.支持文件系統或者裸設備,-filename=/dev/sda2或-filename=/dev/sdb direct=1 bool,true(1)表示測試過程繞過機器自帶的buffer。使測試結果更真實。 rw=randread 隨機讀 rw=randwrite 隨機寫 rw=randrw 隨機混合讀寫 rw=read 順序讀 rw=write 順序寫 rw=rw 順序混合讀寫 rwmixwrite=70 在混合讀寫的模式下,寫占70% bs=4k 單次io的塊文件大小為16k bsrange=512-2048 同上,提定數據塊的大小范圍 size=10G 本次的測試文件大小為10G,以每次4k的io進行測試。 numjobs=30 本次的測試io線程為30. runtime=1000 測試時間為1000秒,如果不寫則一直將設定size為10g文件分4k每次寫完為止。 ioengine=psync 定義job向文件發起IO的方式 iodepth 一個線程一次提交要提交多少個I/O請求,只對異步I/O引擎有用 group_reporting 關於顯示結果的,匯總每個進程的信息。 lockmem=1g 只使用1g內存進行測試 zero_buffers 用0初始化系統buffer nrfiles=8 每個進程生成文件的數量 ioscheduler 在運行之前,嘗試將文件所在的設備切換到指定的調度器。????
ioengine:定義job向文件發起IO的方式,不同的引擎使用不同的函數和實現對測試文件發起訪問。常用的幾個有:
(1)libaio: Linux專有的異步IO,異步引擎。(如果要使用libaio引擎,需要yum install libaio-devel包)
(2)psync/sync: 同步引擎(psync的效果接近異步引擎)
fio --enghelp 查看有哪些ioengine,
fio --enghelp=“引擎名字” 查看對應引擎的幫助
iodepth:
一個線程一次提交要提交多少個I/O請求
這個只對異步I/O引擎有用,因為同步I/O總是會等待提交的I/O請求返回了再提交下一個I/O請求,所以iodepth總是1。
這完全是純應用層面的行為,和盤的IO queue不是一回事。
3、常用命令
-direct=1
-ioengine=psync -iodepth=1(同步) 或 -ioengine=libaio -iodepth=4/8/16/1024(異步)
-rw=read/randread/write/randwrite/randrw
-rwmixread=70
-bs=4k/1M/4M
fio -filename=/dev/sdc -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=1M -size=20G -numjobs=24 -runtime=300 -group_reporting -name=sdc_read_4k -output=/home/judy/fio_result/sdc_read_4k
fio -filename=/dev/sdc -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=1M -size=20G -numjobs=24 -runtime=300 -group_reporting -name=sdc_randread_4k -output=/home/judy/fio_result/sdc_randread_4k
4、結果
(1)參數說明:
io=執行了多少M的IO
bw=IO帶寬
iops=每秒的輸入輸出量(或讀寫次數)
runt=線程運行時間
slat=提交延遲(
submission latency),表示盤需要多久將IO提交到kernel做處理
clat=完成延遲(completion latency),表示提交到kernel到IO做完之間的時間,不包括submission latency
lat=響應時間 (
latency),lat = slat + clat,表示從fio將請求提交給內核,再到內核完成這個I/O為止所需要的時間。
cpu=利用率,用戶/系統CPU占用率
ctx: context ,進程上下文切換(context switch)次數
majf/minf:主要和次要(major and minor)頁面錯誤數量(page faults)。由於測試是配置成使用直接IO,page faults數量應該極少。
IO depths=io隊列
IO submit=單個IO提交要提交的IO數
IO complete=Like the above submit number, but for completions instead.
IO issued=The number of read/write requests issued, and how many of them were short.
IO latencies=IO完延遲的分布
io=總共執行了多少size的IO
aggrb=group總帶寬
minb=最小.平均帶寬.
maxb=最大平均帶寬.
mint=group中線程的最短運行時間.
maxt=group中線程的最長運行時間.
ios=所有group總共執行的IO數.
merge=總共發生的IO合並數.
ticks=Number of ticks we kept the disk busy.
io_queue=花費在隊列上的總共時間.
util=磁盤利用率
(2)結果樣例分析
[root@node2 fio-2.1.10]# fio -filename=/dev/sdc -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=16k -size=10G -numjobs=30 -runtime=100 -group_reporting -name=mytest -ioscheduler=noop mytest: (g=0): rw=randrw, bs=16K-16K/16K-16K/16K-16K, ioengine=psync, iodepth=1 ... fio-2.1.10 Starting 30 threads Jobs: 30 (f=30): [mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm] [100.0% done] [239.9MB/104.5MB/0KB /s] [15.4K/6659/0 iops] [eta 00m:00s] mytest: (groupid=0, jobs=30): err= 0: pid=172663: Tue Oct 22 11:15:05 2019 # Fio支持把不同的測試聚合,設置分組(group)把IO單獨匯總。 read : io=24385MB, bw=249698KB/s, iops=15606, runt=100002msec # IOPS (Input/Output Per Second)即每秒讀寫次數 #iops * bs = io_bw # 每秒提交次數 * 每次提交數據大小 = 每秒io帶寬 clat (usec): min=32, max=20225, avg=1882.78, stdev=1429.20 lat (usec): min=32, max=20225, avg=1882.89, stdev=1429.20 # ipos * lat(s) = jobs * 1(s) # 若同時有r和w,則 r + w = jobs*1(s) clat percentiles (usec): | 1.00th=[ 57], 5.00th=[ 195], 10.00th=[ 478], 20.00th=[ 732], | 30.00th=[ 932], 40.00th=[ 1112], 50.00th=[ 1400], 60.00th=[ 1784], | 70.00th=[ 2352], 80.00th=[ 3216], 90.00th=[ 4016], 95.00th=[ 4640], | 99.00th=[ 5920], 99.50th=[ 6496], 99.90th=[ 7712], 99.95th=[ 8256], | 99.99th=[11840] # "99.99th=[11840]" 表示99.99%請求的響應時間小於等於11840us bw (KB /s): min= 6930, max=10208, per=3.34%, avg=8331.55, stdev=454.58 # 單線程(jobs)的負載 # bw_avg = read_bw / jobs # per = read_bw / bw_avg write: io=10463MB, bw=107134KB/s, iops=6695, runt=100002msec clat (usec): min=30, max=4668, avg=86.21, stdev=40.18 lat (usec): min=31, max=4669, avg=86.80, stdev=40.19 clat percentiles (usec): | 1.00th=[ 42], 5.00th=[ 46], 10.00th=[ 51], 20.00th=[ 61], | 30.00th=[ 67], 40.00th=[ 73], 50.00th=[ 78], 60.00th=[ 83], | 70.00th=[ 91], 80.00th=[ 107], 90.00th=[ 133], 95.00th=[ 155], | 99.00th=[ 201], 99.50th=[ 219], 99.90th=[ 274], 99.95th=[ 318], | 99.99th=[ 972] bw (KB /s): min= 2517, max= 4854, per=3.34%, avg=3573.97, stdev=316.73 lat (usec) : 50=3.07%, 100=22.26%, 250=8.52%, 500=3.52%, 750=7.28% # "50=3.07%"表示 [0~50us),占3.07% lat (usec) : 1000=9.63% lat (msec) : 2=20.55%, 4=18.11%, 10=7.03%, 20=0.02%, 50=0.01% cpu : usr=0.24%, sys=1.12%, ctx=2230918, majf=0, minf=1515 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% #表示所有請求的ipdepth都是1.命令中iodepth設成1,所以IO depth在全部時間都是1 # 若iodepth生效,則 ipos * lat(s) ~= jobs * 1(s) * iodepth (前者略小一點) submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% #submit和complete代表同一時間段內fio發送上去和已完成的IO數量。但 iodepth=1 ????? issued : total=r=1560646/w=669604/d=0, short=r=0/w=0/d=0 # 發送的IO數量,r/(r+w) = 70% =rwmixread。單位是???? latency : target=0, window=0, percentile=100.00%, depth=1 # Fio可以配置一個延遲目標值,這個值可以調節吞吐量直到達到預設的延遲目標。四個值分別代表預設的latency_target, latency_window, latency_percentile和iodepth Run status group 0 (all jobs): READ: io=24385MB, aggrb=249698KB/s, minb=249698KB/s, maxb=249698KB/s, mint=100002msec, maxt=100002msec WRITE: io=10463MB, aggrb=107134KB/s, minb=107134KB/s, maxb=107134KB/s, mint=100002msec, maxt=100002msec #匯總輸出吞吐量和時間: # io:表示總共完成的IO數量。在基於時間的測試中這是一個變量,在基於容量的測試中,這個值能匹配size參數。 # aggrb:是所有進程/設備的匯總帶寬 # minb/maxb表示測量到的最小/最大帶寬 # mint/maxt表示測試的最短和最長耗時。在基於時間的測試應該能匹配runtime參數,對於基於容量的測試是一個變量。
Disk stats (read/write): sdc: ios=1560336/669399, merge=0/0, ticks=2919051/49656, in_queue=2969316, util=100.00%