【技术】FIO测硬盘的IOPS、吞吐量

就是一个磁盘IO测试工具,为什么说这个,是因为研究NAS中的zfs系统后,要测试raid下的一个读写性能IOPS,用这个工具很nice

 

而且FIO 是一个多线程io生成工具,可以生成多种IO模式,用来测试磁盘设备的性能,可以测顺序读写,随机读写 这两大类。另外,fio 还可以对 blktrace 生成的文件进行回放,然后让我们去定位实际系统的 I/O 问题,fio 还支持将中间的操作输出到文件,然后使用工具绘制图表展示

 

此外,还有一个叫iostat的,主要用于监控系统设备的IO负载情况,当然用netdata也行

 

基本参数
参数说明:

首先就是 I/O engine,这个就是告诉 fio 使用什么样的方式去测试 I/O,我们需要根据业务的实际情况选择不同的类型,主要几个:

libaio - Linux 原生的异步 I/O,这也是通常我们这边用的最多的测试盘吞吐和延迟的方法

sync - 也就是最通常的 read / write 操作

vsync - 使用 readv / writev,主要是会将相邻的 I/O 进行合并

psync - 对应的 pread / pwrite,增量同步,一般sync是全量的

pvsync / pvsync2 - 对应的 preadv / pwritev,以及 preadv2 / p writev2

------

filename=/dev/sdb1             测试文件名称,通常选择需要测试的盘的data目录。

direct=1             是否使用directIO,测试过程绕过OS自带的buffer,使测试磁盘的结果更真实。所以有一种模式叫做DirectIO,跳过缓存,直接读写SSD。 

rw=randwrite     测试随机写的I/O

rw=randrw         测试随机写和读的I/O

bs=16k               单次io的块文件大小为16k,也就是一次 I/O 操作的大小,通常我们都是读写使用相同的 block,譬如 bs=4k,但实际还会不一样,我们可以用 bs=4k,16k 来设置读是 4k,但写是 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创建进程。

runtime=1000        测试时间为1000秒,如果不写则一直将5g文件分4k每次写完为止。测试时间runime的值应尽量不低于1h,如果时间很短没有测试实际意义

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扛不住,另一方面这么多命令会很占内存,系统也要挂掉了。这样,就带来一个参数叫做队列深度。

 

rwmixwrite=30         在混合读写的模式下,写占30%

group_reporting       关于显示结果的,汇总每个进程的信息。

此外

lockmem=1g             只使用1g内存进行测试。

zero_buffers              用0初始化系统buffer。

nrfiles=8                    每个进程生成文件的数量。

 

 

磁盘读写常用测试点:

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%随机写)

 

实战解读
这是一台12核CPU+128G DDR4内存+1T数据中心级NVME+10*10TB企业级机械硬盘的机器

配置如下:

root@HPC-HEL1-S101 ~ # zpool iostat -v
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
Hel1-S101 132G 90.8T 0 89 3.30K 1.91M
raidz1 132G 90.8T 0 81 3.30K 991K
sda - - 0 8 333 99.5K
sdb - - 0 7 315 98.6K
sdc - - 0 8 349 99.6K
sdd - - 0 7 334 98.7K
sde - - 0 8 362 99.7K
sdf - - 0 8 326 98.7K
sdg - - 0 8 354 99.6K
sdh - - 0 8 328 98.6K
sdi - - 0 8 349 99.6K
sdj - - 0 8 322 98.5K
logs - - - - - -
loop1 11.8M 298G 0 10 8 1.21M
cache - - - - - -
loop2 224M 300G 0 0 49 81.3K
---------- ----- ----- ----- ----- ----- -----
最新的fio可以在https://github.com/axboe/fio进行下载,但可能会由于系统自带的gcc版本较低导致无法顺利安装。升级gcc后即可顺利安装。升级gcc请参考:https://blog.csdn.net/weixin_40343504/article/details/107843661

 

前面说了,iostat是一个实时监测工具,所以能看到后面operations和bandwidth有一些小小的读写活动,属于正常

这十块盘可以看到是组了raidz1,就是raid5

 

开始IO测试,执行代码

fio -filename=/Hel1-S101/fiotest.bin -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=16k -size=10G -numjobs=30 -runtime=10 -group_reporting -name=zfs-cache-test
这里随机写入测试,增量同步,每个线程都写入总量为10G的文件,但10G文件的单个块大小为16K,30个线程一起,运行10秒(比较恐怖的一个测试)

 

显示结果

Jobs: 30 (f=30): [w(30)][100.0%][w=153MiB/s][w=9782 IOPS][eta 00m:00s]
zfs-cache-test: (groupid=0, jobs=30): err= 0: pid=21034: Thu Jun 4 18:49:56 2020

write: IOPS=11.1k, BW=173MiB/s (182MB/s)(1734MiB/10002msec); 0 zone resets
clat (usec): min=5, max=88218, avg=2700.66, stdev=2176.33
lat (usec): min=6, max=88218, avg=2700.98, stdev=2176.36
clat percentiles (usec):
| 1.00th=[ 10], 5.00th=[ 45], 10.00th=[ 52], 20.00th=[ 816],
| 30.00th=[ 1696], 40.00th=[ 2311], 50.00th=[ 2737], 60.00th=[ 3130],
| 70.00th=[ 3556], 80.00th=[ 3982], 90.00th=[ 4883], 95.00th=[ 6063],
| 99.00th=[ 7373], 99.50th=[ 8291], 99.90th=[18220], 99.95th=[26346],
| 99.99th=[53740]
bw ( KiB/s): min= 3552, max=40271, per=3.33%, avg=5913.96, stdev=4550.90, samples=592
iops : min= 222, max= 2516, avg=369.60, stdev=284.39, samples=592
lat (usec) : 10=1.10%, 20=0.79%, 50=7.09%, 100=5.98%, 250=2.23%
lat (usec) : 500=0.92%, 750=1.26%, 1000=3.18%
lat (msec) : 2=11.54%, 4=46.17%, 10=19.38%, 20=0.29%, 50=0.07%
lat (msec) : 100=0.01%
cpu : usr=0.16%, sys=2.21%, ctx=205649, majf=0, minf=0
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 rwts: total=0,110988,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
WRITE: bw=173MiB/s (182MB/s), 173MiB/s-173MiB/s (182MB/s-182MB/s), io=1734MiB (1818MB), run=10002-10002msec
来解读一下:

w=153MiB/s    写入速度

w=9782 IOPS    写IOPS指标

 

IOPS=11.1k    IOPS值

BW=173MiB/s (182MB/s)(1734MiB/10002msec)    指带宽,平均值173,峰值182,1734MB 每10000微秒(10秒内总共走了1734M数据)

bw 小文件传输时的带宽数值

 

slat=提交延迟,提交该IO请求到kernel所花的时间(不包括kernel处理的时间)

clat=完成延迟, 提交该IO请求到kernel后,处理所花的时间

lat=响应时间,总共花了多少时间

后面是lat测试响应时间的一个分布情况:例如lat (msec)   : 2=11.54%, 4=46.17%, 10=19.38%, 20=0.29%, 50=0.07%,表示在2微秒内有11.54%,4微秒内的有46.17%...以此类推

其实主要看开头,结尾,中间这三个部分就行


IOPS差不多10000,写入带宽速度173M/s

 

再来一个

pingcap: (g=0): rw=write, bs=(R) 8192B-8192B, (W) 8192B-8192B, (T) 8192B-8192B, ioengine=psync, iodepth=1
fio-3.1
Starting 1 process
Jobs: 1 (f=1): [W(1)][100.0%][r=0KiB/s,w=296MiB/s][r=0,w=37.8k IOPS][eta 00m:00s]
pingcap: (groupid=0, jobs=1): err= 0: pid=39086: Thu Apr 12 16:49:02 2018
write: IOPS=37.0k, BW=297MiB/s (311MB/s)(10.0GiB/34510msec)
clat (usec): min=3, max=159, avg= 5.28, stdev= 1.58
lat (usec): min=3, max=159, avg= 5.40, stdev= 1.59
clat percentiles (nsec):
| 1.00th=[ 4048], 5.00th=[ 4192], 10.00th=[ 4256], 20.00th=[ 4384],
| 30.00th=[ 4448], 40.00th=[ 4512], 50.00th=[ 4768], 60.00th=[ 5344],
| 70.00th=[ 5472], 80.00th=[ 5664], 90.00th=[ 6176], 95.00th=[ 8512],
| 99.00th=[10688], 99.50th=[11328], 99.90th=[21632], 99.95th=[22912],
| 99.99th=[27520]
bw ( KiB/s): min=291856, max=348720, per=100.00%, avg=317689.68, stdev=14463.28, samples=66
iops : min=36482, max=43590, avg=39711.20, stdev=1807.88, samples=66
lat (usec) : 4=0.37%, 10=96.95%, 20=2.51%, 50=0.17%, 100=0.01%
lat (usec) : 250=0.01%
cpu : usr=8.55%, sys=43.65%, ctx=1310832, majf=0, minf=149
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 rwt: total=0,1310720,0, short=0,0,0, dropped=0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
WRITE: bw=297MiB/s (311MB/s), 297MiB/s-297MiB/s (311MB/s-311MB/s), io=10.0GiB (10.7GB), run=34510-34510msec

Disk stats (read/write):
nvme0n1: ios=0/1306428, merge=0/22, ticks=0/18431, in_queue=17280, util=50.11%
主要看这几个数值就行


这是一块Optane 盘,固态的,性能很强

 

扩展补充
硬盘性能衡量
衡量硬盘性能,最直观的就是IOPS和吞吐量。

1、IOPS,每秒处理的IO次数 指存储设备(HDD、SSD、SAN)单位时间内能处理的IO请求数量,对随机读写频繁的应用,如OLTP数据库、图片、是最关键的衡量指标。IOPS数值受读写比例、随机IO、IO大小、队列深度等因数影响。数据库通常访问一系列不连续的数据,根据文件物理位置,需要很多次IO才能完成。所以需要随机IO高的设备。

决定因素有:磁盘个数,cache命中率,阵列算法

2、Throughput,吞吐量 指单位时间内可以成功传输的数据数量,传输包括读和写的总和。对于大文件或者流媒体的应用,拥有大量顺序读写,则更关注数据吞吐量。数据吞吐量还受到存储设备接口速度限制,比如IDE、SATA、SAS、FC,SSD使用PCIE Nvme接口最佳,但同时期推出的接口都大于存储设备吞吐量上限。

决定因素有:阵列架构,光纤通道大小,硬盘个数

 

存储性能
1、机械硬盘的性能计算 

对机械硬盘来说,IOPS = 1000 / (寻道时间 + 旋转延时 + 传输时间)。 

 IOPS计算完整公式:

IO Time = Seek Time + 60 sec/Rotational Speed/2 + IO Chunk Size/Transfer Rate

于是计算IOPS公式为:

IOPS = 1/IO Time 

= 1/(Seek Time + 60 sec/Rotational Speed/2 + IO Chunk Size/Transfer Rate)

又因为1s=1000ms,通常时间都是ms级别的,下面公式就用1000来除了

 

寻道时间,磁头移动到对应磁道上的耗时。 Sata 7200RPM,平均寻道时间是9ms。 Sas 10000RPM,平均寻道时间是6ms。 Sas 15000RPM,平均寻道时间是4ms。  

旋转延时,盘片旋转至需要的扇区移至磁头下方耗时。 平均为磁盘旋转一周所需时间的一半,60 * 1000/7200/2。 Sata 7200RPM,旋转延时 60 * 1000 / 7200 / 2 = 4.17ms。 Sas 10000RPM,旋转延时3ms。 Sas 15000RPM,旋转延时约2ms。 

 传输时间,传输读写数据耗时。 平均数据大小除以接口传输率,耗时很小粗略计算可以忽略。 Sata,300~600MB/s。 Sas,3Gbit/s。 FC,2~4Gbit/s。 NVME,32Gbit/s。 根据上述信息,我们常用的Sas 15000RPM,MySQL应用16k块,机械硬盘IOPS = 1000 / (4 + 2 + 16K / 375K) = 165。

 

有人可能看不懂ransfer Rate 375K哪来的,一般就是硬盘固定的传输的速度,那我找了著名的HC550 16T盘的数据,这里看4K,基本读写都在个位数,单位兆,附近,一般机械硬盘7200转的传输,尤其是读取,很难超过1M,都是几百K,所以上述用了375K算是较为老旧一点的盘了,不过差距也没那么大,现在的盘性能更强,那么最后一项接近于0

 

对比一下NVme固态的,也是读取低于写入,但读取大约能超过30M,50-60倍的一个差距,所以如果你用牛X的固态来计算,最后第三个值可以忽略不计

 


2. SSD硬盘IO计算 

固态硬盘没有寻道时间和旋转时间。IO耗时是通过地址查找数据耗时,根据芯片颗粒SLC、MLC,中控芯片、队列深度32~64、接口Sata、PCIE的不同,一般负载非太高时是相对固定值(控制在60%利用率)。 IOPS = 1000 / IO耗时。因为SSD比较固定,比如Intel 320 SSD对8K avgrq-sz耗时0.1ms,1000/0.1ms=10000 IOPS。

 

1、美光(Crucial)M4系列 128G 2.5英寸 SATA-3固态硬盘(CT128M4SSD2)  
500 MB/sec (SATA 6Gb/s),175 MB/sec (SATA 6Gb/s)
随机读取 4k 45,000 IOPS,,随机写入 4k 20,000 IOPS

2、三星(SAMSUNG)830系列 512G 2.5英寸 SATA-3固态硬盘(MZ-7PC512B/WW) 
连续读取:最大 520 MB/秒 连续写入:最大 400MB/秒 

随机读取: 80,000 IOPS 随即写入:最大 36,000 IOPS

3、三星980pro

随机读取 4k 45,000 IOPS,随机写入 4k 20,000 IOPS

 

 

 

3、iops估算raid盘数

如果单盘不能满足性能需求,需要通过Raid实现,计算所需硬盘数公式如下(不同读写策略不一定相同,以下只是常见的一种)

Raid1、10,Drive IOPS = Read IOPS + 2*Write IOPS 

Raid3、5,Drive IOPS = Read IOPS + 4*Write IOPS 

Raid6,Drive IOPS = Read IOPS + 6*Write IOPS 

 

假设需要IOPS 5000,读写比例2:1,则RAID10后IOPS需求为。 RAID10,(2/3) * 5000 + 2 * (1/3) * 5000 = 6666 IOPS c、已知Sas 15000RPM机械硬盘IOPS165。 5000IOPS所需硬盘个数, 6666 / 165 = 40。

 

另外还需要了解raid的写惩罚,参考:

http://www.dostor.com/article/2013-08-26/349588.shtml

 

可用的IOPS = (物理磁盘总的IOPS × 写百分比 ÷ RAID写惩罚) + (物理磁盘总的IOPS × 读百分比)

 

假设组成RAID-5的物理磁盘总共可以提供500 IOPS,使用该存储的应用程序读写比例是50%/50%,那么对于前端主机而言,实际可用的IOPS是:

 

(500 ×50% ÷ 4)+ ( 500 * 50%) = 312.5 IOPS

 

 

4、常见存储设备参考性能,avgrq-sz 8~16K 

5400 rpm SATA,60 IOPS 

7200 rpm SATA,70 IOPS 

10000 rpm SAS,110 IOPS 

15000 rpm SAS,150 IOPS

Sequential RW 180MB/s、Radom RW 15MB/s。 

SSD Sata,3000~40000 IOPS,R 400MB/s、W 250MB/s。

SSD PCIE,20000~40000 IOPS,R 500MB/s、W 300MB/s。 

内存,1000000+ IOPS,30~60 GB/s。

 

5、响应时间和IOPS:

R=T/(1-U) 

R是响应时间 

T是I/O控制器服务一个块所用时间

U是硬盘利用率

 

磁盘利用率越高,磁盘响应时间越慢

因此对于敏感应用,磁盘利用率不要超过70%。即单盘最大实际能提供的IOPS,为MAX(IOPS)*70%

15000rpm的硬盘,最大提供IOPS为180,实际能提供的其实只有180*70%=126

系统实际IOPS越接近理论的最大值,IO的响应时间会成非线性的增长,越是接近最大值,响应时间就变得越大,而且会比预期超出很多。磁盘利用率超过70%,响应时间会急剧上升

 

8K IO Chunk Size (135 IOPS, 7.2 ms)   

135 => 240.0 ms   

105 => 29.5 ms   

75 => 15.7 ms   

45 => 10.6 ms   

 

64K IO Chunk Size(116 IOPS, 8.6 ms)   

135 => 没响应了……   

105 => 88.6 ms   

75 => 24.6 ms   

45 => 14.6 ms

 

6、IOPS和传输速度(吞吐量)的关系:

IOPS和传输速度没有直接关系,不能使用IOPS*块大小=传输速度

在没有缓存的情况下它们共同的决定因素都是对磁盘系统的访问方式以及单个IO的大小。对磁盘进行随机访问时候我们可以利用IOPS来衡量一个磁盘系统的性能,此时的传输速度不会太大

但是当对磁盘进行连续访问时,此时的IOPS已经没有了参考的价值,这个时候限制实际传输速度却是磁盘的最大传输速度

因此在实际的应用当中,只会用IOPS来衡量小IO的随机读写的性能,而当要衡量大IO连续读写的性能的时候就要采用传输速度而不能是IOPS了。 作者:村雨Mura https://www.bilibili.com/read/cv15021687 出处:bilibili

posted @ 2022-07-06 09:21  十支穿云箭  阅读(2238)  评论(0编辑  收藏  举报