目錄
隨看隨用
FIO用法:
隨機讀:(可直接用,向磁盤寫一個2G文件,10線程,隨機讀1分鍾,給出結果)
fio -filename=/tmp/test_randread -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=mytest
說明:
filename=/dev/emcpowerb 支持文件系統或者裸設備,-filename=/dev/sda2或-filename=/dev/sdb
direct=1 測試過程繞過機器自帶的buffer,使測試結果更真實
rw=randwread 測試隨機讀的I/O
rw=randwrite 測試隨機寫的I/O
rw=randrw 測試隨機混合寫和讀的I/O
rw=read 測試順序讀的I/O
rw=write 測試順序寫的I/O
rw=rw 測試順序混合寫和讀的I/O
bs=4k 單次io的塊文件大小為4k
bsrange=512-2048 同上,提定數據塊的大小范圍
size=5g 本次的測試文件大小為5g,以每次4k的io進行測試
numjobs=30 本次的測試線程為30
runtime=1000 測試時間為1000秒,如果不寫則一直將5g文件分4k每次寫完為止
time_based: 如果在runtime指定的時間還沒到時文件就被讀寫完成,將繼續重復直到runtime時間結束。
ioengine=psync io引擎使用pync方式,如果要使用libaio引擎,需要yum install libaio-devel包
rwmixwrite=30 在混合讀寫的模式下,寫占30%
group_reporting 關於顯示結果的,匯總每個進程的信息
此外
lockmem=1g 只使用1g內存進行測試
zero_buffers 用0初始化系統buffer
nrfiles=8 每個進程生成文件的數量
read 順序讀
write 順序寫
rw,readwrite 順序混合讀寫
randwrite 隨機寫
randread 隨機讀
randrw 隨機混合讀寫
io總的輸入輸出量
bw:帶寬 KB/s
iops:每秒鍾的IO數
runt:總運行時間
lat (msec):延遲(毫秒)
msec: 毫秒
usec: 微秒
順序讀:
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=mytest
隨機寫:
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=mytest
順序寫:
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=mytest
混合隨機讀寫:
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=mytest -ioscheduler=noop
原文:https://blog.csdn.net/don_chiang709/article/details/92628623
FIO介紹
FIO是測試IOPS的非常好的工具,用來對磁盤進行壓力測試和驗證。磁盤IO是檢查磁盤性能的重要指標,可以按照負載情況分成照順序讀寫,隨機讀寫兩大類。
FIO是一個可以產生很多線程或進程並執行用戶指定的特定類型I/O操作的工具,IO 是一個多線程io生成工具,可以生成多種IO模式,用來測試磁盤設備的性能(也包含文件系統:如針對網絡文件系統 NFS 的IO測試)。
fio在github上的坐標:https://github.com/axboe/fio 。
查看當前 fio 已支持的 IO 引擎
# fio --enghelp
Available IO engines:
cpuio
mmap
sync
psync
vsync
pvsync
null
net
netsplice
libaio
rdma
posixaio
falloc
e4defrag
splice
rbd
mtd
sg
binject
FIO 工具常用參數:
參數說明:
filename=/dev/sdb1 測試文件名稱,通常選擇需要測試的盤的data目錄。
direct=1 是否使用directIO,測試過程繞過OS自帶的buffer,使測試磁盤的結果更真實。Linux讀寫的時候,內核維護了緩存,數據先寫到緩存,后面再后台寫到SSD。讀的時候也優先讀緩存里的數據。這樣速度可以加快,但是一旦掉電緩存里的數據就沒了。所以有一種模式叫做DirectIO,跳過緩存,直接讀寫SSD。
rw=randwrite 測試隨機寫的I/O
rw=randrw 測試隨機寫和讀的I/O
bs=16k 單次io的塊文件大小為16k
bsrange=512-2048 同上,提定數據塊的大小范圍
size=5G 每個線程讀寫的數據量是5GB。
numjobs=1 每個job(任務)開1個線程,這里=幾個,后面每個用-name指定的任務就開幾個線程測試。所以最終線程數=任務數(幾個name=jobx)* numjobs。
name=job1:一個任務的名字,重復了也沒關系。如果fio -name=job1 -name=job2,建立了兩個任務,共享-name=job1之前的參數。-name之后的就是job2任務獨有的參數。
thread 使用pthread_create創建線程,另一種是fork創建進程。進程的開銷比線程要大,一般都采用thread測試。fio默認會使用fork()創建job,如果這個選項設置的話,fio將使用pthread_create來創建線程。
runtime=1000 測試時間為1000秒,如果不寫 則一直將5g文件分4k每次寫完為止。
ioengine=libaio 指定io引擎使用libaio方式。libaio:Linux本地異步I/O。請注意,Linux可能只支持具有非緩沖I/O的排隊行為(設置為“direct=1”或“buffered=0”);rbd:通過librbd直接訪問CEPH Rados
iodepth=16 隊列的深度為16.在異步模式下,CPU不能一直無限的發命令到SSD。比如SSD執行讀寫如果發生了卡頓,那有可能系統會一直不停的發命令,幾千個,甚至幾萬個,這樣一方面SSD扛不住,另一方面這么多命令會很占內存,系統也要掛掉了。這樣,就帶來一個參數叫做隊列深度。
Block Devices(RBD),無需使用內核RBD驅動程序(rbd.ko)。該參數包含很多ioengine,如:libhdfs/rdma等
rwmixwrite=30 在混合讀寫的模式下,寫占30%
group_reporting
如果‘numjobs’設置的話,我們感興趣的可能是打印group的統計值,而不是一個單獨的job。這在‘numjobs’的值很大時,一般是設置為true的,可以減少輸出的信息量。如果‘group_reporting’設置的話,fio將會顯示最終的per-groupreport而不是每一個job都會顯示。
此外
lockmem=1g 只使用1g內存進行測試。
zero_buffers 用0初始化系統buffer。
nrfiles=8 每個進程生成文件的數量。
a.loops=int
重復運行某個job多次,默認是1。
loops與runtime是兩個不能同時存在的兩個參數,loops主要是定義硬盤執行的圈數,而runtime只是定義fio執行的時間。
b.time_based
如果設置的話,即使file已被完全讀寫或寫完,也要執行完runtime規定的時間。它是通過循環執行相同的負載來實現的,與runtime相對應。
c.ramp_time=time
設定在記錄任何性能信息之前要運行特定負載的時間。這個用來等性能穩定后,再記錄日志結果,因此可以減少生成穩定的結果需要的運行時間。
d.randrepeat=bool
對於隨機IO負載,配置生成器的種子,使得路徑是可以預估的,使得每次重復執行生成的序列是一樣的。
磁盤讀寫常用測試點:
1. Read=100% Ramdon=100% rw=randread (100%隨機讀)
2. Read=100% Sequence=100% rw=read (100%順序讀)
3. Write=100% Sequence=100% rw=write (100%順序寫)
4. Write=100% Ramdon=100% rw=randwrite (100%隨機寫)
5. Read=70% Sequence=100% rw=rw, rwmixread=70, rwmixwrite=30
(70%順序讀,30%順序寫)
6. Read=70% Ramdon=100% rw=randrw, rwmixread=70, rwmixwrite=30
(70%隨機讀,30%隨機寫)
fio例子:
fio --ioengine=rbd --iodepth=10 --numjobs=1 --pool=.rbdpool.rbd --rbdname=lun14 --name=write5 --rw=randwrite --bs=1M --size=6G --group_reporting --direct=1&
[root@rdma63 hsx]# write5: (g=0): rw=randwrite, bs=1M-1M/1M-1M/1M-1M, ioengine=rbd, iodepth=10
fio-2.2.10
Starting 1 process
rbd engine: RBD version: 1.12.0
Jobs: 1 (f=0): [w(1)] [100.0% done] [0KB/109.3MB/0KB /s] [0/109/0 iops] [eta 00m:00s]
write5: (groupid=0, jobs=1): err= 0: pid=4074401: Wed Jan 27 10:17:15 2021
write: io=6144.0MB, bw=108918KB/s, iops=106, runt= 57763msec
slat (usec): min=254, max=20470, avg=512.86, stdev=635.57
clat (msec): min=14, max=273, avg=91.68, stdev=32.76
lat (msec): min=15, max=274, avg=92.20, stdev=32.76
clat percentiles (msec):
| 1.00th=[ 37], 5.00th=[ 49], 10.00th=[ 55], 20.00th=[ 64],
| 30.00th=[ 71], 40.00th=[ 79], 50.00th=[ 87], 60.00th=[ 95],
| 70.00th=[ 106], 80.00th=[ 121], 90.00th=[ 139], 95.00th=[ 151],
| 99.00th=[ 182], 99.50th=[ 194], 99.90th=[ 233], 99.95th=[ 269],
| 99.99th=[ 273]
bw (KB /s): min=58810, max=138686, per=100.00%, avg=109173.18, stdev=10441.08
lat (msec) : 20=0.03%, 50=6.04%, 100=58.74%, 250=35.11%, 500=0.08%
cpu : usr=4.28%, sys=1.12%, ctx=920, majf=0, minf=272282
IO depths : 1=2.9%, 2=12.6%, 4=43.1%, 8=41.5%, 16=0.0%, 32=0.0%, >=64=0.0%
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=90.1%, 8=5.5%, 16=4.5%, 32=0.0%, 64=0.0%, >=64=0.0%
issued : total=r=0/w=6144/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0
latency : target=0, window=0, percentile=100.00%, depth=10Run status group 0 (all jobs):
WRITE: io=6144.0MB, aggrb=108918KB/s, minb=108918KB/s, maxb=108918KB/s, mint=57763msec, maxt=57763msecDisk stats (read/write):
sdq: ios=0/1805, merge=0/52, ticks=0/77, in_queue=76, util=0.11%
bw=平均IO帶寬
io=執行了多少M的IO
iops=IOPS
runt=線程運行時間
slat=提交延遲,提交該IO請求到kernel所花的時間(不包括kernel處理的時間)
clat=完成延遲, 提交該IO請求到kernel后,處理所花的時間
lat=響應時間
cpu=利用率
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完延遲的分布
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=磁盤利用率
fio 有很多測試任務配置文件,在git工程 examples 文件夾中,我們可以使用命令行參數進行直接配置,也可以直接通過配置文件配置一次測試的內容。
更詳細對fio輸出說明請參考博文:Fio Output Explained
[root@docker sda]# fio -ioengine=libaio -bs=4k -direct=1 -thread -rw=read -filename=/dev/sda -name="BS 4KB read test" -iodepth=16 -runtime=60
BS 4KB read test: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=16
fio-3.7
Starting 1 thread
Jobs: 1 (f=1): [R(1)][100.0%][r=89.3MiB/s,w=0KiB/s][r=22.9k,w=0 IOPS][eta 00m:00s]
BS 4KB read test: (groupid=0, jobs=1): err= 0: pid=18557: Thu Apr 11 13:08:11 2019
read: IOPS=22.7k, BW=88.5MiB/s (92.8MB/s)(5313MiB/60001msec)
slat (nsec): min=901, max=168330, avg=6932.34, stdev=1348.82 //提交延遲,提交該IO請求到kernel所花的時間(不包括kernel處理的時間)
clat (usec): min=90, max=63760, avg=698.08, stdev=240.83 //完成延遲, 提交該IO請求到kernel后,處理所花的時間 (stdev:標准差)
lat (usec): min=97, max=63762, avg=705.17, stdev=240.81 //響應時間
clat percentiles (usec): //clat (提交延時)的排名分布
| 1.00th=[ 619], 5.00th=[ 627], 10.00th=[ 627], 20.00th=[ 635],
| 30.00th=[ 635], 40.00th=[ 685], 50.00th=[ 717], 60.00th=[ 725],
| 70.00th=[ 725], 80.00th=[ 725], 90.00th=[ 734], 95.00th=[ 816],
| 99.00th=[ 1004], 99.50th=[ 1020], 99.90th=[ 1057], 99.95th=[ 1057],
| 99.99th=[ 1860]
bw ( KiB/s): min=62144, max=91552, per=100.00%, avg=90669.02, stdev=3533.77, samples=120
iops : min=15536, max=22888, avg=22667.27, stdev=883.44, samples=120
lat (usec) : 100=0.01%, 250=0.01%, 500=0.01%, 750=93.85%, 1000=5.14%
lat (msec) : 2=0.99%, 4=0.01%, 10=0.01%, 50=0.01%, 100=0.01%
cpu : usr=5.35%, sys=23.17%, ctx=1359692, majf=0, minf=17
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0% //IO depths=io隊列
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% //單個IO提交要提交的IO數
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0% //Like the above submit number, but for completions instead.
issued rwts: total=1360097,0,0,0 short=0,0,0,0 dropped=0,0,0,0 //The number of read/write requests issued, and how many of them were short.
latency : target=0, window=0, percentile=100.00%, depth=16 //IO完延遲的分布
Run status group 0 (all jobs):
READ: bw=88.5MiB/s (92.8MB/s), 88.5MiB/s-88.5MiB/s (92.8MB/s-92.8MB/s), io=5313MiB (5571MB), run=60001-60001msec
Disk stats (read/write):
sda: ios=1357472/0, merge=70/0, ticks=949141/0, in_queue=948776, util=99.88%(磁盤利用率)
fio工作參數可以寫入配置文件
http://xiaqunfeng.cc/2017/07/12/fio-test-ceph/
測試librbd
1、創建一個image
rbd -p rbd create --size 2048 fio_test
2、撰寫 job file:rbd.fio
######################################################################
# Example test for the RBD engine.
#
# Runs a 4k random write test agains a RBD via librbd
#
# NOTE: Make sure you have either a RBD named 'fio_test' or change
# the rbdname parameter.
######################################################################
[global]
#logging
#write_iops_log=write_iops_log
#write_bw_log=write_bw_log
#write_lat_log=write_lat_log
ioengine=rbd
clientname=admin
pool=rbd
rbdname=fio_test
invalidate=0 # mandatory
rw=randwrite
bs=4k
[rbd_iodepth32]
iodepth=32
以上 job file 將執行整個RBD大小的100%隨機寫入測試(將通過librbd確定),Ceph用戶 admin 使用Ceph 默認 pool rbd和剛剛創建的空的 RBD fio_test,寫的 blocksize 為 4k 和 iodepth 為32 。 引擎正在使用異步IO。
當前實施限制:
- invalidate = 0 現在是強制需要的,engine 現在沒有這個會返回失敗。
- 測試完成后
rbd引擎不會被清除。完成測試運行后,給定的RBD將被填充。(我們現在使用它進行預填充測試,並在需要時重新創建RBD。)
部分參考:Ceph Performance Analysis: fio and RBD
3、測試
fio rbd.fio
IO狀態監控:
進行磁盤測試的時候,我們可以使用iostat 等監控工具,查看所有磁盤當前的讀寫狀態(fedora 系統上 sysstat-11.7.3-2.fc29.x86_64 收錄了此工具)。
監控磁盤IO命令:iostat –mx 1
Iostat介紹
iostat主要用於監控系統設備的IO負載情況,iostat首次運行時顯示自系統啟動開始的各項統計信息,之后運行iostat將顯示自上次運行該命令以后的統計信息。用戶可以通過指定統計的次數和時間來獲得所需的統計信息。
語法
iostat [ -c ] [ -d ] [ -h ] [ -N ] [ -k | -m ] [ -t ] [ -V ] [ -x ] [ -z ] [ device [...] | ALL ] [ -p [ device [,...] | ALL ] ] [ interval [ count ] ]
iostat使用范例:
iostat -d -x -k 1 10
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 1.56 28.31 7.80 31.49 42.51 2.92 21.26 1.46 1.16 0.03 0.79 2.62 10.28
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 2.00 20.00 381.00 7.00 12320.00 216.00 6160.00 108.00 32.31 1.75 4.50 2.17 84.20
-d: 顯示該設備的狀態的參數;
-x:是一個比較常用的選項,該選項將用於顯示和io相關的擴展數據。
-k: 靜態顯示每秒的統計(單位kilobytes )
1: 第一個數字表示每隔1秒刷新一次數據顯示。
10:第二個數字表示總共的刷新次數
輸出信息的含義
rrqm/s:每秒這個設備相關的讀取請求有多少被Merge了(當系統調用需要讀取數據的時候,VFS將請求發到各個FS,如果FS發現不同的讀取請求讀取的是相同Block的數據,FS會將這個請求合並Merge);
wrqm/s:每秒這個設備相關的寫入請求有多少被Merge了。
r/s: 該設備的每秒完成的讀請求數(merge合並之后的)
w/s: 該設備的每秒完成的寫請求數(merge合並之后的)
rsec/s:每秒讀取的扇區數;
wsec/:每秒寫入的扇區數。
rKB/s:每秒發送給該設備的總讀請求數
wKB/s:每秒發送給該設備的總寫請求數
avgrq-sz 平均請求扇區的大小
avgqu-sz 是平均請求隊列的長度。毫無疑問,隊列長度越短越好。
await: 每一個IO請求的處理的平均時間(單位是微秒毫秒)。這里可以理解為IO的響應時間,一般地系統IO響應時間應該低於5ms,如果大於10ms就比較大了。這個時間包括了隊列時間和服務時間,也就是說,一般情況下,await大於svctm,它們的差值越小,則說明隊列時間越短,反之差值越大,隊列時間越長,說明系統出了問題。
svctm: 表示平均每次設備I/O操作的服務時間(以毫秒為單位)。如果svctm的值與await很接近,表示幾乎沒有I/O等待,磁盤性能很好,如果await的值遠高於svctm的值,則表示I/O隊列等待太長,系統上運行的應用程序將變慢。
%util: 在統計時間內所有處理IO時間,除以總共統計時間。例如,如果統計間隔1秒,該設備有0.8秒在處理IO,而0.2秒閑置,那么該設備的%util = 0.8/1 = 80%,所以該參數暗示了設備的繁忙程度。一般地,如果該參數是100%表示設備已經接近滿負荷運行了(當然如果是多磁盤,即使%util是100%,因為磁盤的並發能力,所以磁盤使用未必就到了瓶頸)。
參考:
linux 磁盤IO測試工具:FIO (同時簡要介紹dd工具測試)
與FIO相似的工具
vdbench 、mdtest、dd
fio測試腳本
#!/bin/bash
set -e
ioengine="libaio"
iodepth=128
direct=1
fsync=1
runtime=600
size="10G"
mntdir="/mnt/fio-data/"
mkdir -p /mnt/fio-data
mount /dev/vdb /mnt/fio-data || true
for m in seq rand
do
prefix=""
if [ "$m" == "seq" ] ; then
bs="1024K"
else
bs="4K"
prefix="rand"
fi
for op in read write
do
cat <<EOF >$mntdir/fio-$m-$op.fio
[global]
fsync=$fsync
name=fio-$m-$op
filename=fio-$m-$op
rw=$prefix$op
bs=$bs
direct=$direct
numjobs=1
time_based=1
runtime=$runtime
[file1]
size=$size
ioengine=$ioengine
iodepth=$iodepth
EOF
done
done
docker rm -f $(docker ps -a -q) >/dev/null 2>&1|| true
echo "test case: $c"
outdir=`pwd`/result-`date "+%Y%m%d%H%M"`
mkdir -p $outdir
for p in `ls -1 $mntdir/*.fio`
do
f=`basename $p`
echo 3 > /proc/sys/vm/drop_caches
cmd="docker run --name=$f -v $mntdir:/tmp/fio-data -e JOBFILES=/tmp/fio-data/$f \
clusterhq/fiotools-aio bash /opt/run.sh \
| tee -a $outdir/$f.log"
echo $cmd
eval $cmd
sleep 1
done
提取iops和bw
#!/usr/bin/python2.7
import os
import re
from pathlib import Path
def get_perf(file, type, perf):
m = re.compile('\s*{}\s*: .* {}=(\d+)'.format(type, perf))
with open(file) as f:
for line in f.readlines():
g = m.search(line)
if g is not None and len(g.groups()) == 1:
return g.groups()[0]
raise Exception("{} {} not found".format(type, perf))
def parse(dir, perf):
data = []
perf_type = 'rand' if perf == 'iops' else 'seq'
dirs = Path(dir).glob('result-*/')
for d in dirs:
f = os.path.join(d.name, 'fio-%s-read.fio.log' % perf_type)
read = get_perf(f, "read", perf)
f = os.path.join(d.name, 'fio-%s-write.fio.log' % perf_type)
write = get_perf(f, "write", perf)
data.append((read, write))
return data
if __name__ == '__main__':
cwd = os.path.dirname(os.path.realpath(__file__))
data = parse(cwd, "iops")
with open("iops.txt", "w") as f:
i = 1
for l in data:
f.write('{} {} {}\n'.format(i, l[0], l[1]))
i = i + 1
data = parse(cwd, "bw")
with open("bw.txt", "w") as f:
i = 1
for l in data:
f.write('{} {} {}\n'.format(i, l[0], l[1]))
i = i + 1
gunplot畫圖
- iops
#!/bin/bash
data=iops.txt
pic=iops.png
/usr/local/bin/gnuplot << EOF
set autoscale # scale axes automatically
set xtic 1 # set xtics automatically
set ytic 1000 # set ytics automatically
set title "IOPS over Time"
set xlabel "samples over time"
set ylabel "iops"
set grid
set term png medium
set term png size 953, 620
set key box top left
set output "$pic"
plot "$data" using 1:2 title "read" with linespoints, \
"$data" using 1:3 title "write" with linespoints
quit
EOF
Fio 輸出內容的解釋
https://blog.csdn.net/feilianbb/article/details/50497845
翻譯原文來源
https://tobert.github.io/post/2014-04-17-fio-output-explained.html
read : io=10240MB, bw=63317KB/s, iops=15829, runt=165607msec
fio做了10GB的IO,速率63.317MB/s,總IOPS 15829 (默認4k block size),運行了2分鍾45秒。
slat,或稱為submission latency。代表“盤需要多久將IO提交到kernel做處理?”。
slat (usec): min=3, max=335, avg= 9.73, stdev= 5.76
clat,completion latency。命令提交到kernel到IO做完之間的時間,不包括submission latency。在老版本的fio中,這是估計應用級延遲的最好指標。
clat (usec): min=1, max=18600, avg=51.29, stdev=16.79
lat (usec): min=44, max=18627, avg=61.33, stdev=17.91
'lat'是一個新的指標,似乎這個值是從IO結構體創建時刻開始,直到緊接着clat完成,這個算法最好地表現出了應用程序的行為。
clat percentiles (usec):
| 1.00th=[ 42], 5.00th=[ 45], 10.00th=[ 45], 20.00th=[ 46],
| 30.00th=[ 47], 40.00th=[ 47], 50.00th=[ 49], 60.00th=[ 51],
| 70.00th=[ 53], 80.00th=[ 56], 90.00th=[ 60], 95.00th=[ 67],
| 99.00th=[ 78], 99.50th=[ 81], 99.90th=[ 94], 99.95th=[ 101],
| 99.99th=[ 112]
Completion latency百分數的解釋一目了然,可能是輸出信息中最有用的部分。我看了代碼,這不是slat+clat,而是用了單獨的結構體記錄。
這個列表可以在config文件中配置。在精簡輸出模式下有20個這樣的格式,%f=%d; %f=%d;... 解析這樣的輸出格式會很有趣。
clat percentiles (usec):
| 1.00th=[ 3952], 5.00th=[ 5792], 10.00th=[ 7200], 20.00th=[ 8896],
| 30.00th=[10304], 40.00th=[11456], 50.00th=[12608], 60.00th=[13760],
| 70.00th=[15168], 80.00th=[16768], 90.00th=[18816], 95.00th=[20608],
| 99.00th=[23424], 99.50th=[24192], 99.90th=[26752], 99.95th=[28032],
| 99.99th=[30080]
bw (KB /s): min=52536, max=75504, per=67.14%, avg=63316.81, stdev=4057.09
帶寬(bandwidth)的意思顯而易見,而per=part就不是很好理解。文檔上說這個值是指在單個盤上跑多個負載,可以用來看每個進程消耗了多少IO。對於我這樣把fio跑在多個盤的情況,這個值意義不大。但由於SSD和機械硬盤混合使用,這個值挺有趣。
下面是另一個SAS硬盤,占測試的所有4個盤總IO的0.36%。
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分布,第三行使用了毫秒(ms),使得文本寬度可控。把第三行讀成2000, 4000, 10000, 20000微秒(us)就更清晰了。說明了51.41%的request延遲小於50微秒,48.53%的延遲小於100微秒(但是大於50微秒),以此類推。
cpu : usr=5.32%, sys=21.95%, ctx=2829095, majf=0, minf=21
這是用戶/系統CPU占用率,進程上下文切換(context switch)次數,主要和次要(major and minor)頁面錯誤數量(page faults)。由於測試是配置成使用直接IO,page faults數量應該極少。
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
Fio有一個iodepth設置,用來控制同一時刻發送給OS多少個IO。這完全是純應用層面的行為,和盤的IO queue不是一回事。這里iodepth設成1,所以IO depth在全部時間都是1。
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%
通常來說,只有iodepth大於1才需要關注這一部分數據。,submit和complete代表同一時間段內fio發送和已完成的IO數量。對於產生這個輸出的垃圾回收測試用例來說,iodepth是默認值1,所以100%的IO在同一時刻發送1次,放在1-4欄位里。
issued : total=r=2621440/w=0/d=0, short=r=0/w=0/d=0
發送的IO數量。這里出現了奇怪的現象,因為這是50/50的讀寫負載,照道理應該有相同數量的write。我猜測把unified_rw_reporting打開是的fio把所有的IO都認為是read。
如果你在直接IO測試是看到了IO值很低,那么可能是出問題了。我在Linux kernel中找到參考說這種現象發生在文件末尾EOL或可能是設備的尾端。
latency : target=0, window=0, percentile=100.00%, depth=1
Fio可以配置一個延遲目標值,這個值可以調節吞吐量直到達到預設的延遲目標。我還沒有太多深入了解這部分。在基於時間或和容量的測試中,這行通常看起來一樣。四個值分別代表預設的latency_target, latency_window, latency_percentile和iodepth。
Run status group 0 (all jobs):
Fio支持把不同的測試聚合。例如,我可以用一個配置文件混合包含SSD和HDD,但是設置分組(group)把IO單獨匯總。我現在還沒涉及這個功能,但未來會用到。
MIXED: io=12497MB, aggrb=42653KB/s, minb=277KB/s, maxb=41711KB/s, mint=300000msec, maxt=300012msec
最后,匯總輸出吞吐量和時間。
io=表示總共完成的IO數量。在基於時間的測試中這是一個變量,在基於容量的測試中,這個值能匹配size參數。
aggrb是所有進程/設備的匯總帶寬。
minb/maxb表示測量到的最小/最大帶寬。
mint/maxt表示測試的最短和最長耗時。和io=參數類似,時間值對於基於時間的測試應該能匹配runtime參數,對於基於容量的測試是一個變量。
由於我設置了unified_rw_reporting參數運行測試,所以只看到MIXED一行。如果禁用這個參數,對於讀和寫會有單獨的行。
夠簡單吧?我未來的幾周會花更多的時間研究fio,我會發布更多關於配置,輸出和圖表代碼的例子。
