SSD性能测试第一神器:FIO
SSD性能测试第一神器:FIO
对于SSD性能测试来说,最好的工具莫过于FIO了。
上面这个可爱的小伙子名字叫Jens Axboe,他是丹麦哥本哈根大学计算机系没毕业的学生,他还有一个有名的同乡叫Linus,没想到老乡后来也成了他的领导。Jens今年(2017年)40岁,16岁开始就接触Linux,后来也成了Linux开发者,现在是Linux Kernel大拿了,负责块设备层的维护。这个块设备层就是跟我们SSD关系最紧密的层级,联系了上层文件系统和下层设备驱动程序。他开发了不少有用的程序,比如Linux IO Scheduler里面的Deadline, CFQ Scheduler,还有著名的王牌测试工具FIO。 Jens曾经在Fusion-IO、Oracle等公司工作,现在在Facebook,阿呆听说在硅谷Facebook给码农的薪水是最高的。
FIO是Jens开发的一个开源测试工具,功能非常强大,本文就只介绍其中一些基本功能。
线程,队列深度,Offset,同步异步,DirectIO,BIO
使用FIO之前,首先要有一些SSD性能测试的基础知识。
线程指的是同时有多少个读或写任务在并行执行,一般来说,CPU里面的一个核心同一时间只能运行一个线程。如果只有一个核心,要想运行多线程,只能使用时间切片,每个线程跑一段时间片,所有线程轮流使用这个核心。Linux使用Jiffies来代表一秒钟被划分成了多少个时间片,一般来说Jiffies是1000或100,所以时间片就是1毫秒或10毫秒。
一般电脑发送一个读写命令到SSD只需要几微秒,但是SSD要花几百微秒甚至几毫秒才能执行完这个命令。如果发一个读写命令,然后线程一直休眠,等待结果回来才唤醒处理结果,这种叫做同步模式。可以想象,同步模式是很浪费SSD性能的,因为SSD里面有很多并行单元,比如一般企业级SSD内部有8-16个数据通道,每个通道内部有4-16个并行逻辑单元(LUN,Plane),所以同一时间可以执行32-256个读写命令。同步模式就意味着,只有其中一个并行单元在工作,暴殄天物。
为了提高并行性,大部分情况下SSD读写采用的是异步模式。就是用几微秒发送命令,发完线程不会傻傻的在那里等,而是继续发后面的命令。如果前面的命令执行完了,SSD通知会通过中断或者轮询等方式告诉CPU,CPU来调用该命令的回调函数来处理结果。这样的好处是,SSD里面几十上百个并行单元大家都能分到活干,效率暴增。
不过,在异步模式下,CPU不能一直无限的发命令到SSD。比如SSD执行读写如果发生了卡顿,那有可能系统会一直不停的发命令,几千个,甚至几万个,这样一方面SSD扛不住,另一方面这么多命令会很占内存,系统也要挂掉了。这样,就带来一个参数叫做队列深度。举个例子,队列深度64就是说,系统发的命令都发到一个大小为64的队列,如果填满了就不能再发。等前面的读写命令执行完了,队列里面空出位置来,才能继续填命令。
一个SSD或者文件有大小,测试读写的时候设置Offset就可以从某个偏移地址开始测试。比如从offset=4G的偏移地址开始。
Linux读写的时候,内核维护了缓存,数据先写到缓存,后面再后台写到SSD。读的时候也优先读缓存里的数据。这样速度可以加快,但是一旦掉电缓存里的数据就没了。所以有一种模式叫做DirectIO,跳过缓存,直接读写SSD。
Linux读写SSD等块设备使用的是BIO,Block-IO,这是个数据结构,包含了数据块的逻辑地址LBA,数据大小和内存地址等。
FIO初体验
一般Linux系统是自带FIO的,如果没有或者版本太老,要自己从https://github.com/axboe/fio 下载最新版本源代码编译安装。进入代码主目录,输入下列命令就编译安装好了。
1
|
./configure;make && make install
|
帮助文档用下面命令查看:
1
|
man fio
|
先来看一个简单的例子:
1
|
fio -rw=randwrite -ioengine=libaio -direct=1 –thread –numjobs=1 -iodepth=64 -filename=/dev/sdb4 -size=10G -name=job1 -offset=0MB -bs=4k -name=job2 -offset=10G -bs=512 --output TestResult.log
|
每一项的意思都可以从fio帮助文档是:
fio:软件名称。
-rw=randwrite:读写模式,randwrite是随机写测试,还有顺序读read,顺序写write,随机读randread,混合读写等。
-ioengine=libaio:libaio指的是异步模式,如果是同步就要用sync。
-direct=1:是否使用directIO。
-thread:使用pthread_create创建线程,另一种是fork创建进程。进程的开销比线程要大,一般都采用thread测试。
–numjobs=1:每个job是1个线程,这里用了几,后面每个用-name指定的任务就开几个线程测试。所以最终线程数=任务数* numjobs。
-iodepth=64:队列深度64.
-filename=/dev/sdb4:数据写到/dev/sdb4这个盘(块设备)。这里可以是一个文件名,也可以是分区或者SSD。也可以写一个目录里面的多个文件。
-size=10G:每个线程写入数据量是10GB。
-name=job1:一个任务的名字,名字随便起,重复了也没关系。这个例子指定了job1和job2,建立了两个任务,共享-name=job1之前的参数。-name之后的就是这个任务独有的参数。
-offset=0MB:从偏移地址0MB开始写。
-bs=4k:每一个BIO命令包含的数据大小是4KB。一般4KB IOPS测试,就是在这里设置。
–output TestResult.log:日志输出到TestResult.log。
FIO结果解析
我们来看一个FIO测试随机读的结果。命令如下,2个任务并行测试,队列深度64,异步模式,每个任务测试数据1GB,每个数据块4KB。所以,这个命令是在测试两个线程、队列深度64下的4KB随机读IOPS。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# fio -rw=randread -ioengine=libaio -direct=1 -iodepth=64 -filename=/dev/sdc -size=1G -bs=4k -name=job1 -offset=0G -name=job2 -offset=10G
job1: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=64
job2: (g=0): rw=randread, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=64
fio-2.13
Starting 2 processes
Jobs: 2 (f=2)
job1: (groupid=0, jobs=1): err= 0: pid=27752: Fri Jul 28 14:16:50 2017
read : io=1024.0MB, bw=392284KB/s, iops=98071, runt= 2673msec
slat (usec): min=6, max=79, avg= 9.05, stdev= 2.04
clat (usec): min=148, max=1371, avg=642.89, stdev=95.08
lat (usec): min=157, max=1380, avg=651.94, stdev=95.16
clat percentiles (usec):
| 1.00th=[ 438], 5.00th=[ 486], 10.00th=[ 516], 20.00th=[ 564],
| 30.00th=[ 596], 40.00th=[ 620], 50.00th=[ 644], 60.00th=[ 668],
| 70.00th=[ 692], 80.00th=[ 724], 90.00th=[ 756], 95.00th=[ 796],
| 99.00th=[ 884], 99.50th=[ 924], 99.90th=[ 1004], 99.95th=[ 1048],
| 99.99th=[ 1144]
lat (usec) : 250=0.01%, 500=6.82%, 750=81.14%, 1000=11.93%
lat (msec) : 2=0.11%
cpu : usr=9.09%, sys=90.08%, ctx=304, majf=0, minf=98
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.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.1%, >=64=0.0%
issued : total=r=262144/w=0/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=64
job2: (groupid=0, jobs=1): err= 0: pid=27753: Fri Jul 28 14:16:50 2017
read : io=1024.0MB, bw=447918KB/s, iops=111979, runt= 2341msec
slat (usec): min=5, max=41, avg= 6.30, stdev= 0.79
clat (usec): min=153, max=1324, avg=564.61, stdev=100.40
lat (usec): min=159, max=1331, avg=570.90, stdev=100.41
clat percentiles (usec):
| 1.00th=[ 354], 5.00th=[ 398], 10.00th=[ 430], 20.00th=[ 474],
| 30.00th=[ 510], 40.00th=[ 540], 50.00th=[ 572], 60.00th=[ 596],
| 70.00th=[ 620], 80.00th=[ 644], 90.00th=[ 684], 95.00th=[ 724],
| 99.00th=[ 804], 99.50th=[ 844], 99.90th=[ 932], 99.95th=[ 972],
| 99.99th=[ 1096]
lat (usec) : 250=0.03%, 500=27.57%, 750=69.57%, 1000=2.79%
lat (msec) : 2=0.04%
cpu : usr=11.62%, sys=75.60%, ctx=35363, majf=0, minf=99
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.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.1%, >=64=0.0%
issued : total=r=262144/w=0/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=64
Run status group 0 (all jobs):
READ: io=2048.0MB, aggrb=784568KB/s, minb=392284KB/s, maxb=447917KB/s, mint=2341msec, maxt=2673msec
Disk stats (read/write):
sdc: ios=521225/0, merge=0/0, ticks=277357/0, in_queue=18446744073705613924, util=100.00%
|
FIO会为每个Job打印统计信息。最后面是合计的数值。我们一般看重的总的性能和延迟。
首先看的是最后总的带宽,aggrb=784568KB/s,算成4KB就是196K IOPS。
再来看看延迟Latency。Slat是发命令时间,slat (usec): min=6, max=79, avg= 9.05, stdev= 2.04说明最短时间6微秒,最长79微秒,平均9微秒,标准差2.04。clat是命令执行时间,lat就是总的延迟。看得出来,读的平均延迟在571微秒左右。
clat percentiles (usec)给出了延迟的统计分布。比如90.00th=[ 684]说明90%的读命令延迟都在684微秒以内。
用FIO做数据校验
用FIO可以检验写入数据是否出错。用-verify=str来选择校验算法,有md5 crc16 crc32 crc32c crc32c-intel crc64 crc7 sha256 sha512 sha1等。为了校验,需要用do_verify参数。如果是写,那么do_verify=1就意味着写完再读校验,这种会很占内存,因为FIO会把每个数据块的校验数据保存在内存里。do_verify=0时只写校验数据,不做读校验。
读的时候do_verify=1,那么读出来的数据都会做校验值检查,do_verify=0的话,只读数据,不做检查。
另外,verify=meta时,fio会在数据块内写入时间戳、逻辑地址等,此时还能verify_pattern指定写入数据pattern。
FIO其他功能
FIO功能非常强大,可以通过man来查看每一个功能,也有网页版帮助文档https://linux.die.net/man/1/fio。
FIO配置文件
前面的例子都是用命令行来测试,其实也可以用配置文件把这些参数写进去。比如新建FIO配置文件test.log内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[global]
filename=/dev/sdc
direct=1
iodepth=64
thread
rw=randread
ioengine=libaio
bs=4k
numjobs=1
size=10G
[job1]
name=job1
offset=0
[job2]
name=job2
offset=10G
;--end job file
|
保存后,只需要fio test.log就能执行测试任务了。是不是很方便?
原文:ssdfans
SSD性能测试第一神器:FIO的更多相关文章
- SSD测试第一神器——FIO
原文 地址 http://www.ssdfans.com/ssd%E6%B5%8B%E8%AF%95%E7%AC%AC%E4%B8%80%E7%A5%9E%E5%99%A8-fio-2/ 对于SSD性 ...
- 戴尔笔记本Inspiron 7560(灵越) 加装固态硬盘从选购固态硬盘到系统迁移到设置SSD为第一启动(受不了了,网上的教程就没有完整的)
菜鸡我的笔记本为戴尔灵越Inpsiron 7560,其实Inspiron 15 7560 和Inspiron 7560是同一个型号. 电脑拆了安过内存条,换过电池,现在又加了一块固态硬盘. 因为不想安 ...
- 磁盘性能测试工具之fio
fio是测试磁盘性能的一个非常好的工具,用来对硬件进行压力测试和验证. 注意事项 CentOS 6.5等较老版本的操作系统用fdisk创建分区时,默认为非4KB对齐选择初始磁柱编号,对性能有较大的影响 ...
- HDD ,SSD和PCIE SSD性能测试
PCIE SSD * MB/s = 1,000,000 bytes/s [SATA/600 = 600,000,000 bytes/s] * KB = 1000 bytes, KiB = 10 ...
- Windows server 2008 SSD性能测试
过渡到windows 7.windows8是趋势,老迈的windows xp .windows server 2003已经快到淘汰的阶段,安装了windows server 2008 R2 ,测试了下 ...
- SSD性能测试
Tested by CrystalDiskMark 7 * MB/s = 1,000,000 bytes/s [SATA/600 = 600,000,000 bytes/s]* KB = 1000 b ...
- dd 工具使用; SSD 顺序写性能测试;
dd 工具使用: dd 也是我们经常使用到的磁盘测试工具,Linux服务器装好系统之后,想要知道硬盘的读写是否能满足服务的需要,如果不满足硬盘的IO就是服务的一个瓶颈.我们可以使用dd命令简单进行测试 ...
- SAS SATA SSD基本介绍
SATA硬盘采用新的设计结构,数据传输快,节省空间,相对于IDE硬盘具有很多优势: 1 .SATA硬盘比IDE硬盘传输速度高.目前SATA可以提供150MB/s的高峰传输速率.今后将达到300 MB/ ...
- 【转】花开正当时,十四款120/128GB SSD横向评测
原文地址:http://www.expreview.com/19604-all.html SSD横评是最具消费指导意义的评测文章,也是各类热门SSD固态硬盘的决斗疆场.SSD评测在行业内已经有不少网站 ...
随机推荐
- DokuWiki 插件使用
本身DokuWiki提供了一些公共,但是不是很强大,所以可以安装一些插件. 安装方法可以参考:https://www.dokuwiki.org/extensions 下面列举出我觉得好用的一些插件: ...
- Zabbix监控进程(进程消失后钉钉报警)
用于python报警的脚本如下:(钉钉机器人的连接需要修改) #!/usr/bin/python3# -*- coding: utf-8 -*-# Author: aiker@gdedu.ml# My ...
- MYSQL SQL语句技巧初探(一)
MYSQL SQL语句技巧初探(一) 本文是我最近了解到的sql某些方法()组合实现一些功能的总结以后还会更新: rand与rand(n)实现提取随机行及order by原理的探讨. Bit_and, ...
- Numpy学习笔记(二)
(1)NumPy - 切片和索引 l ndarray对象中的元素遵循基于零的索引. 有三种可用的索引方法类型: 字段访问,基本切片和高级索引. l 基本切片 Python 中基本切片概念到 n 维 ...
- React开发笔记
项目环境搭建 使用create-react-app CSS使用styled-components yarn add styled-components 引入reset.css样式 import { c ...
- JDK1.7 ConcurrentHashMap--解决高并发下的HashMap使用问题
高并发下也可以使用HashTable .Collections.synchronizedMap因为他们是线程安全的,但是却牺牲了性能,无论是读操作.写操作都是给整个集合加锁,导致同一时间内其他操作均为 ...
- python 列表复制给另一个列表,改值两个列表均会改变(备忘)
http://blog.csdn.net/lc_lc2000/article/details/53135839 本意是使A = B,B为一个列表,结果在后续对A的操作中,导致B中的值也改变了,才回忆起 ...
- <记录>TP5 关联模型使用(嵌套关联、动态排序以及隐藏字段)
在数据库设计中,常常会有如下这种关联模型,分类表中一条分类对应多个商品表中的商品 如果要获得分类表中每条分类 以及 对应的商品的信息,则需要先查询分类表中的数据,然后根据结果遍历查询商品表,最后把数据 ...
- VS2017打包设置
本文为网络贴文,引用于:http://www.cnblogs.com/overstep/p/6942423.html 一. 安装打包插件: 安装打包插件:Microsoft Visual Studi ...
- 【FZSZ2017暑假提高组Day2】圆盘时钟
[问题描述] 作为出题人的小Z相信大家对上图这样的圆盘时钟都不会陌生——在理想圆盘时钟上,秒针每一分钟转一圈,分针每一小时转一圈,时针每12小时转一圈,它们均是匀速转动的,在0点时三条针均指向表盘上的 ...