Linux下磁碟I/O測試

大雄45發表於2021-08-31
導讀 目前主流的第三方IO測試工具有[neiqian]fio[/neiqian]、[neiqian]iometer[/neiqian]和[neiqian]Orion[/neiqian],這三種工具各有千秋。

fio在 下使用比較方便, iometer在window系統下使用比較方便, Orion是oracle的IO測試軟體,可在沒有安裝oracle資料庫的情況下模擬oracle資料庫場景的讀寫。

如下是在 系統上採用 fio工具來對SAN儲存進行的IO測試。

1、安裝fio

方法一:在fio官網下載fio-2.1.10.tar檔案,解壓後 ./configuremakemake install之後就可以使用fio了。

方法二:在Linux系統下透過 yum安裝, yum install -y fio

2、[neiqian]fio[/neiqian]引數解釋

可以使用 fio -help檢視每個引數,具體的引數左右可以在官網檢視how to文件,如下為幾個常見的引數描述

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每次寫完為止
ioengine=psync io引擎使用pync方式,如果要使用libaio引擎,需要yum install libaio-devel包
rwmixwrite=30 在混合讀寫的模式下,寫佔30%
group_reporting 關於顯示結果的,彙總每個程式的資訊
此外
lockmem=1g 只使用1g記憶體進行測試
zero_buffers 用0初始化系統buffer
nrfiles=8 每個程式生成檔案的數量
3、fio測試場景及生成報告詳解
測試場景:

100%隨機,100%讀, 4K

fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=rand_100read_4k

100%隨機,100%寫, 4K

fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=rand_100write_4k

100%順序,100%讀 ,4K

fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100read_4k

100%順序,100%寫 ,4K

fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100write_4k

100%隨機,70%讀,30%寫 4K

fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=randrw_70read_4k

結果報告檢視:

[root@rac01-node02]# fio -filename=/dev/sdc4 -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=randrw_70read_4k_local
randrw_70read_4k_local: (g=0): rw=randrw, bs=4K-4K/4K-4K/4K-4K, ioengine=psync, iodepth=1
...
fio-2.1.10
Starting 50 threads
Jobs: 21 (f=21): [mm_m_m__mmmmmm__mm_m_mmm_mm__m_m_m] [3.4% done] [7004KB/2768KB/0KB /s] [1751/692/0 iops] [eta 01h:27m:00s]
randrw_70read_4k_local: (groupid=0, jobs=50): err= 0: pid=13710: Wed May 31 10:23:31 2017
read : io=1394.2MB, bw=7926.4KB/s, iops=1981, runt=180113msec
clat (usec): min=39, max=567873, avg=24323.79, stdev=25645.98
lat (usec): min=39, max=567874, avg=24324.23, stdev=25645.98
clat percentiles (msec):
| 1.00th=[ 3], 5.00th=[ 5], 10.00th=[ 6], 20.00th=[ 7],
| 30.00th=[ 9], 40.00th=[ 12], 50.00th=[ 16], 60.00th=[ 21],
| 70.00th=[ 27], 80.00th=[ 38], 90.00th=[ 56], 95.00th=[ 75],
| 99.00th=[ 124], 99.50th=[ 147], 99.90th=[ 208], 99.95th=[ 235],
| 99.99th=[ 314]
bw (KB /s): min= 15, max= 537, per=2.00%, avg=158.68, stdev=38.08
write: io=615280KB, bw=3416.8KB/s, iops=854, runt=180113msec
clat (usec): min=167, max=162537, avg=2054.79, stdev=7665.24
lat (usec): min=167, max=162537, avg=2055.38, stdev=7665.23
clat percentiles (usec):
| 1.00th=[ 201], 5.00th=[ 227], 10.00th=[ 249], 20.00th=[ 378],
| 30.00th=[ 548], 40.00th=[ 692], 50.00th=[ 844], 60.00th=[ 996],
| 70.00th=[ 1160], 80.00th=[ 1304], 90.00th=[ 1720], 95.00th=[ 3856],
| 99.00th=[40192], 99.50th=[58624], 99.90th=[98816], 99.95th=[123392],
| 99.99th=[148480]
bw (KB /s): min= 6, max= 251, per=2.00%, avg=68.16, stdev=29.18
lat (usec) : 50=0.01%, 100=0.03%, 250=3.15%, 500=5.00%, 750=5.09%
lat (usec) : 1000=4.87%
lat (msec) : 2=9.64%, 4=4.06%, 10=21.42%, 20=18.08%, 50=19.91%
lat (msec) : 100=7.24%, 250=1.47%, 500=0.03%, 750=0.01%
cpu : usr=0.07%, sys=0.21%, ctx=522490, majf=0, minf=7
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 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=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued : total=r=356911/w=153820/d=0, short=r=0/w=0/d=0
latency : target=0, window=0, percentile=100.00%, depth=1
Run status group 0 (all jobs):
READ: io=1394.2MB, aggrb=7926KB/s, minb=7926KB/s, maxb=7926KB/s, mint=180113msec, maxt=180113msec
WRITE: io=615280KB, aggrb=3416KB/s, minb=3416KB/s, maxb=3416KB/s, mint=180113msec, maxt=180113msec
Disk stats (read/write):
sdc: ios=356874/153927, merge=0/10, ticks=8668598/310288, in_queue=8978582, util=99.99%
io=執行了多少M的IO
bw=平均IO頻寬
iops=IOPS
runt=執行緒執行時間
slat=提交延遲
clat=完成延遲
lat=響應時間
bw=頻寬
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完延遲的分佈
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=磁碟利用率
4、擴充套件之IO佇列深度

在某個時刻,有N個i nflight的IO請求,包括在佇列中的IO請求、磁碟正在處理的IO請求。N就是佇列深度。
加大硬碟佇列深度就是讓硬碟不斷工作,減少硬碟的空閒時間。
加大佇列深度 -->提高利用率 -->獲得IOPS和MBPS峰值 -->注意響應時間在可接受的範圍內,
增加佇列深度的辦法有很多,使用非同步IO,同時發起多個IO請求,相當於佇列中有多個IO請求,多執行緒發起同步IO請求,相當於佇列中有多個IO請求。
增大應用IO大小,到達底層之後,會變成多個IO請求,相當於佇列中有多個IO請求 佇列深度增加了。
佇列深度增加了,IO在佇列的等待時間也會增加,導致IO響應時間變大,這需要權衡。

為何要對磁碟I/O進行並行處理呢?主要目的是提升應用程式的效能。這一點對於多物理磁碟組成的虛擬磁碟(或 LUN)顯得尤為重要。
如果一次提交一個I/O,雖然響應時間較短,但系統的吞吐量很小。
相比較而言,一次提交多個I/O既縮短了磁頭移動距離(透過電梯演算法),同時也能夠提升 IOPS
假如一部電梯一次只能搭乘一人,那麼每個人一但乘上電梯,就能快速達到目的地(響應時間),但需要耗費較長的等待時間(佇列長度)。
因此一次向磁碟系統提交多個I/O能夠平衡吞吐量和整體響應時間。

Linux系統檢視預設佇列深度:

[root@qsdb ~]# lsscsi -l
[0:0:0:0] disk DGC VRAID 0533 /dev/sda
state=running queue_depth=30 scsi_level=5 type=0 device_blocked=0 timeout=30
[0:0:1:0] disk DGC VRAID 0533 /dev/sdb
state=running queue_depth=30 scsi_level=5 type=0 device_blocked=0 timeout=30
[2:0:0:0] disk DGC VRAID 0533 /dev/sdd
state=running queue_depth=30 scsi_level=5 type=0 device_blocked=0 timeout=30
[2:0:1:0] disk DGC VRAID 0533 /dev/sde
state=running queue_depth=30 scsi_level=5 type=0 device_blocked=0 timeout=30
[4:2:0:0] disk IBM ServeRAID M5210 4.27 /dev/sdc
state=running queue_depth=256 scsi_level=6 type=0 device_blocked=0 timeout=90
[9:0:0:0] cd/dvd Lenovo SATA ODD 81Y3677 IB00 /dev/sr0
state=running queue_depth=1 scsi_level=6 type=5 device_blocked=0 timeout=30
使用dd 設定bs=2M進行測試:
dd if=/dev/zero of=/dev/sdd bs=2M count=1000 oflag=direct

記錄了1000+0 的讀入 記錄了1000+0 的寫出 2097152000位元組(2.1 GB)已複製,10.6663 秒,197 MB/秒

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sdd 0.00 0.00 0.00 380.60 0.00 389734.40 1024.00 2.39 6.28 2.56 97.42

可以看到2MB的IO到達底層之後,會變成多個512KB的IO,平均佇列長度為2.39,這個硬碟的利用率是97%,MBPS達到了197MB/s。
(為什麼會變成512KB的IO,你可以去使用Google去查一下核心引數  max_sectors_kb的意義和使用方法 )也就是說增加佇列深度,是可以測試出硬碟的峰值的。

5、Linux系統中檢視IO iostat詳解
[root@rac01-node01 /]# iostat -xd 3
Linux 3.8.13-16.2.1.el6uek.x86_64 (rac01-node01) 05/27/2017 _x8664 (40 CPU)
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 0.05 0.75 2.50 0.50 76.59 69.83 48.96 0.00 1.17 0.47 0.14
scd0 0.00 0.00 0.02 0.00 0.11 0.00 5.25 0.00 21.37 20.94 0.05
dm-0 0.00 0.00 2.40 1.24 75.88 69.83 40.00 0.01 1.38 0.38 0.14
dm-1 0.00 0.00 0.02 0.00 0.14 0.00 8.00 0.00 0.65 0.39 0.00
sdc 0.00 0.00 0.01 0.00 0.11 0.00 10.20 0.00 0.28 0.28 0.00
sdb 0.00 0.00 0.01 0.00 0.11 0.00 10.20 0.00 0.15 0.15 0.00
sdd 0.00 0.00 0.01 0.00 0.11 0.00 10.20 0.00 0.25 0.25 0.00
sde 0.00 0.00 0.01 0.00 0.11 0.00 10.20 0.00 0.14 0.14 0.00
輸出引數描述:
rrqms:每秒這個裝置相關的讀取請求有多少被Merge了(當系統呼叫需要讀取資料的時候,VFS將請求發到各個FS,如果FS發現不同的讀取請求讀取的是相同Block的資料,FS會將這個請求合併Merge)
wrqm/s:每秒這個裝置相關的寫入請求有多少被Merge了。
rsec/s:The number of sectors read from the device per second.
wsec/s:The number of sectors written to the device per second.
rKB/s:The number of kilobytes read from the device per second.
wKB/s:The number of kilobytes written to the device per second.
avgrq-sz:平均請求扇區的大小,The average size (in sectors) of the requests that were issued to the device.
avgqu-sz:是平均請求佇列的長度。毫無疑問,佇列長度越短越好,The average queue length of the requests that were issued to the device.
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%,因為磁碟的併發能力,所以磁碟使用未必就到了瓶頸)。

原文來自:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2789763/,如需轉載,請註明出處,否則將追究法律責任。

相關文章