https://www.cnblogs.com/lyhabc/p/16708771.html

简介

一般我们测试硬盘或者存储的性能的时候,会用Linux系统自带的dd命令,因为是自带命令,简单易使用,因此一些客户喜欢使用dd命令来测试磁盘的读写性能。

但是用dd命令来测试性能,有如下问题:

1. dd命令的IO模型单一,只能测试顺序IO,不能测试随机IO。

2. dd命令可设置的参数较少,并且测试结果不一定能反映出磁盘的真实性能。

3. dd命令的设计初衷就不是用例测试性能的,在dd的手册中可以看到。

4. 无法设置队列深度,因此不推荐用dd命令来测试最大读IOPS。

因此,我们要使用更专业的磁盘性能测试工具来测试,目前主流的第三方IO测试工具有fio、iometer和Orion。

iometer 是Windows下使用方便,Orion是Oracle的IO测试软件,而FIO是我们比较常用的在Linux系统下(当然在Windows下安装cygwin也可以运行FIO)的IO系统Benchmark和压力测试工具,可以模拟不同IO场景下的IO负载。

FIO支持 13种不同的 I/O 引擎, 包括:sync,mmap, libaio, posixaio, SG v3, splice, null, network,syslet,guasi,solarisaio 等等。

根据实际业务的场景,一般将 I/O 的表现分为四种场景,随机读、随机写、顺序读、顺序写。FIO 工具允许指定具体的应用模式,配合多线程对磁盘进行不同深度的测试。

安装

FIO默认已经存在于yum仓库里,所以我们yum安装即可

yum install -y libaio-devel
yum install -y fio-3.7-2.el7.x86_64

运行格式

fio [options] [job options] <job file(s)>

工作原理

使用 FIO 工具测试硬盘性能,首先确定待模拟IO负载的IO参数,如I/O type,Block size,I/O engine,I/O depth,Target file/device等

然后需要编写一个作业(命令行或者脚本job file)来预定义 FIO 将要以什么样的模式来执行任务。

作业中可以包含任意数量的线程或文件,一个作业的典型模式是定义一部分的全局共享参数global 段和一个(或多个)作业的job 段实体对象(即硬盘)。

运行 FIO 作业时,FIO 会自上而下解析作业中的配置,并做相应的调整去执行任务。

测试完成后,输出测试结果,对FIO测试结果进行分析,评估IO系统的设计或优化方案或确定debug思路。

FIO 中的常用选项如下
filename: 支持文件系统或者裸设备(硬盘或分区),-filename=/dev/sda2 或 -filename=/tmp/fio_read_test.txt 或 -filename=/dev/sda
direct: 1表示测试过程绕过机器自带的buffer,相当于o_direct,0表示使用bufferio
runtime:测试时长,单位秒,如果不写则直接写5GB文件
time_based: 如果在runtime指定的时间还没到时文件就被读写完成,将继续重复直到runtime时间结束,加上这个参数防止job提前结束。
size: 向硬盘中写入/读取测试文件的大小,可以是绝对值MB,KB,GB,也可以是百分比,占所测磁盘的百分比%,
group_reporting:汇总所有的信息,而不是每个job都显示具体的结果
thread:fio默认会使用fork()创建job进程,如果这个选项设置的话,fio将使用pthread_create来创建线程
numjobs:创建的线程或进程数量,建议等于 CPU 的 core 值,,如果要测试吞吐量,那么numjobs要设置小一点
rw: 读写方式,顺序读read,顺序写write,随机读randread ,随机写randwrite,混合读写randrw,如果要测试吞吐量,需要设为顺序读read,顺序写write
rwmixread:70,混合读写7:3 ,配合rw = randrw
rwmixwrite:30 在混合读写的模式下7:3
bs: 单次io的块大小,一般测试4k, 8k, 64k, 128k, 1M
bsrange: =512-2048 同上,提定数据块的大小范围
allow_mounted_write:允许虚拟机写入
ioengine:FIO 工作时使用的引擎。引擎决定了使用什么样的 I/O,同步模式、异步模式,如果要使用libaio引擎,需要yum install -y libaio-devel包,要使用异步模式引擎才能设置iodepth
iodepth:I/O 引擎如果使用异步模式,要保持多少的队列深度,没有设置则使用操作系统默认队列深度,如果要测试吞吐量,那么iodepth要设置小一点
nrfiles:每个进程/线程生成文件的数量,表示负载将分发到几个文件中。

使用测试

编写 FIO 任务文件

要执行一个 FIO 任务前,需要先定义一个 FIO 任务作业。

按参数输入方式分为如下两种作业定义方式:
(1) 命令行方式(命令行方式一次测试一个磁盘):如fio   –filename=/dev/sdb –direct=1 –rw=randread –bs=4k –size=60G –numjobs=64 –runtime=10 –group_reporting –name=test
(2) fio job_file 方式(job_file方式一次测试多个磁盘,每个磁盘写在不同的job段,官方推荐这种方式):如job_file 的名字为 test,则运行方式为 fio test。
按FIO工作模式分为如下两种:
(1)client/server方式:FIO工作模式可以分为前端和后端,即client端和server端。server端执行fio --server,client端执行fio --client=hostname jobfile,这样client端就可以把jobfile发到server端来执行,hostname为server端的IP。
(2)本地执行:命令行   job file。

FIO 任务脚本模板,如果filename写在global段其他job段不写filename,则跟命令行一样,一次只测试一个磁盘

cat fio.conf
[global]
ioengine=libaio
iodepth=4
direct=1
runtime=60
time_based=1
size=1G
group_reporting=1
thread=1
numjobs=2
bs=4k
name='test'
allow_mounted_write=1
nrfiles=1
#filename=/data/total.txt [seqread]
rw=read
filename=/data/fio_read_test.txt [seqwrite]
rw=write
filename=/data/fio_write_test.txt

上面的job_file文件转换为命令行形式就是下面的样子

#read 顺序读
fio -ioengine=libaio -direct=1 -bs=4k -nrfiles=1 -thread -rw=read -size=1G -filename=/data/fio_read_test.txt -name='test' -iodepth=4 -runtime=30 -numjobs=2 -time_based=1 -allow_mounted_write=1 -group_reporting #write 顺序写
fio -ioengine=libaio -direct=1 -bs=4k -nrfiles=1 -thread -rw=write -size=1G -filename=/data/fio_write_test.txt -name='test' -iodepth=4 -runtime=30 -numjobs=2 -time_based=1 -allow_mounted_write=1 -group_reporting

测试结果解读

--------------------------------------------------------------------
展示测试的基本信息
fio fio.conf
seqread: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=4
...
seqwrite: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=4
...
fio-3.7
Starting 4 threads --------------------------------------------------------------------
总共4个job, seqread是2线程,所以是2,seqwrite是2线程,所以是2,加起来4 Jobs: 4 (f=4): [R(2),W(2)][100.0%][r=89.3MiB/s,w=188KiB/s][r=22.9k,w=47 IOPS][eta 00m:00s]
--------------------------------------------------------------------
重点看这里
IOPS 最大IOPS
BW 最大带宽
延时时间
slat表示磁盘需要多久将io提交到kernel做处理
clat表示命令提交到了内核,提交到内核到io完成的时间。
Lat表示从io结果提创建到clat完成,一般说时延,就是看这个值。
clat各个延时所占的百分比。 seqread: (groupid=0, jobs=4): err= 0: pid=11385: Thu Sep 22 17:09:31 2022
read: IOPS=20.5k, BW=80.0MiB/s (83.9MB/s)(4803MiB/60015msec)
slat (nsec): min=1, max=163324k, avg=53835.94, stdev=297380.37
clat (usec): min=50, max=1179.2k, avg=330.98, stdev=4855.59
lat (usec): min=99, max=1179.2k, avg=386.15, stdev=4864.96
clat percentiles (usec):
| 1.00th=[ 113], 5.00th=[ 116], 10.00th=[ 119], 20.00th=[ 123],
| 30.00th=[ 127], 40.00th=[ 131], 50.00th=[ 137], 60.00th=[ 141],
| 70.00th=[ 153], 80.00th=[ 314], 90.00th=[ 367], 95.00th=[ 388],
| 99.00th=[ 490], 99.50th=[ 898], 99.90th=[ 58983], 99.95th=[ 90702],
| 99.99th=[160433]
bw ( KiB/s): min= 7, max=85555, per=50.24%, avg=41180.02, stdev=16441.93, samples=238
iops : min= 1, max=21388, avg=10294.83, stdev=4110.45, samples=238 --------------------------------------------------------------------
同上
write: IOPS=41, BW=165KiB/s (169kB/s)(9952KiB/60190msec)
slat (usec): min=13, max=42741, avg=118.82, stdev=1177.06
clat (msec): min=2, max=1708, avg=193.14, stdev=118.53
lat (msec): min=2, max=1708, avg=193.26, stdev=118.48
clat percentiles (msec):
| 1.00th=[ 33], 5.00th=[ 77], 10.00th=[ 97], 20.00th=[ 120],
| 30.00th=[ 142], 40.00th=[ 161], 50.00th=[ 182], 60.00th=[ 205],
| 70.00th=[ 228], 80.00th=[ 255], 90.00th=[ 288], 95.00th=[ 321],
| 99.00th=[ 472], 99.50th=[ 726], 99.90th=[ 1703], 99.95th=[ 1703],
| 99.99th=[ 1703]
bw ( KiB/s): min= 7, max= 230, per=50.76%, avg=83.76, stdev=35.04, samples=235
iops : min= 1, max= 57, avg=20.55, stdev= 8.71, samples=235 --------------------------------------------------------------------
lat指的是时延,50=0.06%,表示有0.06%的io时延小于50ms。
lat (usec) : 100=0.08%, 250=77.12%, 500=21.64%, 750=0.40%, 1000=0.09%
lat (msec) : 2=0.09%, 4=0.09%, 10=0.11%, 20=0.03%, 50=0.05%
lat (msec) : 100=0.09%, 250=0.17%, 500=0.04%, 750=0.01%, 1000=0.01% --------------------------------------------------------------------
usr表示用户cpu占用率,sys表示系统cpu占用率,ctx为上下文切换次数,majf是主要页面错误数量, minf是次要页面错误数量 cpu : usr=3.85%, sys=27.45%, ctx=20221, majf=0, minf=18
--------------------------------------------------------------------
队列深度,Submit和complete表示同一时段fio发送和完成的io数据量。Issued为发送的io数量,latency用于调节吞吐量直到达到预设的延迟目标。 IO depths : 1=0.1%, 2=0.1%, 4=100.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=1229695,2488,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=4 --------------------------------------------------------------------
最后是结果的汇总
util:磁盘利用率 Run status group 0 (all jobs):
READ: bw=80.0MiB/s (83.9MB/s), 80.0MiB/s-80.0MiB/s (83.9MB/s-83.9MB/s), io=4803MiB (5037MB), run=60015-60015msec
WRITE: bw=165KiB/s (169kB/s), 165KiB/s-165KiB/s (169kB/s-169kB/s), io=9952KiB (10.2MB), run=60190-60190msec Disk stats (read/write):
sdb: ios=1229695/2526, merge=0/8, ticks=287074/481664, in_queue=767911, util=100.00% --------------------------------------------------------------------

关于IO队列深度

在某个时刻,有N个inflight的IO请求,也就是缓冲的IO请求,包括在队列中的IO请求,而N就是队列深度。

加大硬盘队列深度就是让硬盘不断工作,减少硬盘的空闲时间。

加大队列深度 -> 提高IO利用率 -> 获得更高的IOPS和MBPS峰值 ,但是队列深度增加了,IO在队列的等待时间也会增加,导致IO响应时间变大,这个是值得考虑的问题。

就好比一部电梯一次只能搭乘一人,那么每个人一但乘上电梯,就能快速达到目的楼层(单个IO响应时间),但其他人需要耗费较长的等待时间(总IO响应时间)

如果增加电梯容量(队列深度)一次搭乘五个人,那么低楼层的人能快速到达目的楼层(单个IO响应时间),高楼层的人需要耗费多一点点时间(总IO响应时间)

为何要对磁盘I/O进行队列化处理呢?主要目的是提升应用程序的性能。这一点对于多物理磁盘组成的虚拟磁盘(或LUN)显得尤为重要。

如果一次提交一个I/O,虽然响应时间较短,但系统的吞吐量很小。相比较而言,一次提交多个I/O既缩短了磁头移动距离(通过电梯算法),同时也能够提升IOPS。

因此一次向磁盘系统提交多个I/O能够平衡吞吐量和整体响应时间。

在Centos7下下查看系统默认的队列深度

lsscsi -l
[1:0:0:0] cd/dvd NECVMWar VMware IDE CDR10 1.00 /dev/sr0
state=running queue_depth=1 scsi_level=6 type=5 device_blocked=0 timeout=30
[2:0:0:0] disk VMware Virtual disk 1.0 /dev/sda
state=running queue_depth=32 scsi_level=3 type=0 device_blocked=0 timeout=180
[2:0:1:0] disk VMware Virtual disk 1.0 /dev/sdb
state=running queue_depth=32 scsi_level=3 type=0 device_blocked=0 timeout=180

FIO 任务命令行模板,filename需要指定被测磁盘所在分区路径

#read 顺序读 吞吐量
fio -ioengine=libaio -direct=1 -bs=4k -thread -rw=read -size=10G -nrfiles=1 -filename=fio_readputth_test.txt -name='fio read test' -iodepth=2 -runtime=120 -numjobs=4 -time_based=1 -allow_mounted_write=1 -group_reporting #write 顺序写 吞吐量
fio -ioengine=libaio -direct=1 -bs=4k -thread -rw=write -size=10G -nrfiles=1 -filename=fio_writeputth_test.txt -name='fio write test' -iodepth=2 -runtime=120 -numjobs=4 -time_based=1 -allow_mounted_write=1 -group_reporting #read 顺序读
fio -ioengine=libaio -direct=1 -bs=4k -thread -rw=read -size=2G -nrfiles=1 -filename=fio_read_test.txt -name='fio read test' -iodepth=4 -runtime=60 -numjobs=8 -time_based=1 -allow_mounted_write=1 -group_reporting #write 顺序写
fio -ioengine=libaio -direct=1 -bs=4k -thread -rw=write -size=2G -nrfiles=1 -filename=fio_write_test.txt -name='fio write test' -iodepth=4 -runtime=60 -numjobs=8 -time_based=1 -allow_mounted_write=1 -group_reporting #readwrite 顺序混合读写
fio -ioengine=libaio -direct=1 -bs=4k -thread -rw=readwrite -size=2G -nrfiles=1 -filename=fio_readwrite_test.txt -name='fio readwrite test' -iodepth=4 -runtime=60 -numjobs=8 -time_based=1 -allow_mounted_write=1 -group_reporting #randread 随机读
fio -ioengine=libaio -direct=1 -bs=4k -thread -rw=randread -size=2G -nrfiles=1 -filename=fio_randread_test.txt -name='fio randread test' -iodepth=4 -runtime=60 -numjobs=8 -time_based=1 -allow_mounted_write=1 -group_reporting #randwrite 随机写
fio -ioengine=libaio -direct=1 -bs=4k -thread -rw=randwrite -size=2G -nrfiles=1 -filename=fio_randwrite_test.txt -name='fio randwrite test' -iodepth=4 -runtime=60 -numjobs=8 -time_based=1 -allow_mounted_write=1 -group_reporting #randrw 随机混合读写
fio -ioengine=libaio -direct=1 -bs=4k -thread -rw=randrw -size=2G -nrfiles=1 -filename=fio_randrw_test.txt -name='fio randrw test' -iodepth=4 -runtime=60 -numjobs=8 -time_based=1 -allow_mounted_write=1 -group_reporting

最后,我们可以把结果汇总到表格,方便把报告递给领导

[转帖]FIO磁盘性能测试工具的更多相关文章

  1. 磁盘性能测试工具之fio

    fio是测试磁盘性能的一个非常好的工具,用来对硬件进行压力测试和验证. 注意事项 CentOS 6.5等较老版本的操作系统用fdisk创建分区时,默认为非4KB对齐选择初始磁柱编号,对性能有较大的影响 ...

  2. 6款实用的硬盘、SSD固态硬盘、U盘、储存卡磁盘性能测试工具

    一.检测工具名称汇总 HDTune ATTO Disk Benchmark CrystalDiskMark AS SSD Benchmark Parkdale CrystalDiskInfo 二.各项 ...

  3. 5款实用的硬盘、SSD固态硬盘、U盘、储存卡磁盘性能测试工具绿色版

    http://www.iplaysoft.com/disk-benchmark-tools.html/comment-page-1#comment-149425

  4. Linux系统性能测试工具(五)——磁盘io性能工具之fio

    本文介绍关于Linux系统(适用于centos/ubuntu等)的磁盘io性能测试工具-fio.磁盘io性能测试工具包括: fio: dd

  5. Linux系统性能测试工具(六)——磁盘io性能工具之dd

    本文介绍关于Linux系统(适用于centos/ubuntu等)的磁盘io性能测试工具-dd.磁盘io性能测试工具包括: fio: dd

  6. 【转帖】比df命令更有用的磁盘信息工具

    比df命令更有用的磁盘信息工具 http://embeddedlinux.org.cn/emb-linux/entry-level/201310/30-2666.html 除了df fdisk 还有这 ...

  7. Ceph性能测试工具和方法。

    0. 测试环境 同 Ceph 的基本操作和常见故障排除方法 一文中的测试环境. 1. 测试准备 1.1 磁盘读写性能 1.1.1 单个 OSD 磁盘写性能,大概 165MB/s. root@ceph1 ...

  8. 理解 OpenStack + Ceph (8): 基本的 Ceph 性能测试工具和方法

    本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...

  9. ceph--磁盘和rbd、rados性能测试工具和方法

    我在物理机上创建了5台虚拟机,搭建了一个ceph集群,结构如图: 具体的安装步骤参考文档:http://docs.ceph.org.cn/start/ http://www.centoscn.com/ ...

  10. 基本的Ceph性能测试工具和方法

    测试环境 1. 测试准备 1.1 磁盘读写性能 1.1.1 单个 OSD 磁盘写性能,大概 165MB/s. root@ceph1:~# echo 3 > /proc/sys/vm/drop_c ...

随机推荐

  1. 2023-06-01:讲一讲Redis常见数据结构以及使用场景。

    2023-06-01:讲一讲Redis常见数据结构以及使用场景. 答案2023-06-01: 字符串(String) 适合场景 缓存功能 Redis 作为缓存层,MySQL 作为存储层,在大部分请求中 ...

  2. 12、FlutterMediaQuery获取屏幕宽度和高度

    final size =MediaQuery.of(context).size; class HomePage3 extends StatelessWidget { const HomePage3({ ...

  3. 如何应对Spark-Redis行海量数据插入、查询作业时碰到的问题

    摘要:由于redis是基于内存的数据库,稳定性并不是很高,尤其是standalone模式下的redis.于是工作中在使用Spark-Redis时也会碰到很多问题,尤其是执行海量数据插入与查询的场景中. ...

  4. 云图说丨应用宕机怎么办?MAS帮您实现业务无缝切换

    摘要: 多云高可用服务(Multi-cloud high Availability Service,简称MAS)源自华为消费者多云应用高可用方案,提供从流量入口.数据到应用层的端到端的业务故障切换及容 ...

  5. 面对 Log4j2 漏洞,安全人都做了什么?

    摘要:本文从漏洞复现.漏洞防护.漏洞检测.软件供应链安全等方面,介绍安全人针对该漏洞做的尝试. 本文分享自华为云社区<面对 Log4j2 漏洞,安全人都做了什么?>,作者:maijun. ...

  6. CentOS 7上安装 Jenkins 2.346 -- yum 方式

    CentOS 7上安装 Jenkins -- yum 方式 装插件太麻烦了,最后选择了 装JAVA 11,安装最版本 Jenkins https://mirrors.jenkins.io/war/ 开 ...

  7. Docker 安装 ELK,EFK代替

    ELK 版本因为 前面 Elasticsearch 用的 7.9.3 版本,所以 kibana-7.9.3.logstash-7.9.3 都用 7.9.3 版本 安装配置 Elasticsearch ...

  8. Codeforces Round 908 (Div. 2)

    总结 T1 题目大意: A,B两人玩游戏,游戏规则如下: 整场游戏有多轮,每轮游戏先胜 \(X\) 局的人获胜,每场游戏先胜 \(Y\) 局的人获胜. 你在场边观看了比赛,但是你忘记了 \(x\) 和 ...

  9. 聊聊损失函数1. 噪声鲁棒损失函数简析 & 代码实现

    今天来聊聊非常规的损失函数.在常用的分类交叉熵,以及回归均方误差之外,针对训练样本可能存在的数据长尾,标签噪声,数据不均衡等问题,我们来聊聊适用不同场景有针对性的损失函数.第一章我们介绍,当标注标签存 ...

  10. Codeforces Round #481 (Div. 3) 经典几道思维题

    A - AAA POJ - 3321 给你一颗树,支持两种操作 1.修改某一节点的权值 2.查询子树的权值(子树中节点的个数) 很显然可以用树状数组/线段树维护 B - BBB CodeForces ...