fio(Flexible I/O Tester)正是非常常用的文件系统和磁盘 I/O 性能基准测试工具。提供了大量的可定制化选项,可以用来测试,裸盘、一个单独的分区或者文件系统在各种场景下的 I/O 性能,包括了不同块大小、不同 I/O 引擎以及是否使用缓存等场景。

ubuntu安装fio非常简单

root@nvme:~# apt install -y fio

fio选项比较多,可以通过man fio查看,下面是比较常用的几个参数及说明

  • direct,表示是否跳过系统缓存,1表示跳过系统缓存。
  • iodepth,表示使用异步 I/O(asynchronous I/O,简称 AIO,ioengine=libaio)时,同时发出的 I/O 请求上限。
  • rw,表示 I/O 模式。read/write 分别表示顺序读 / 写,而 randread/randwrite 则分别表示随机读 / 写,randrw配合rwmixwrite分别表示混合测试及写占比。
  • ioengine,表示 I/O 引擎,它支持同步(sync)、异步(libaio)、内存映射(mmap)、网络(net)等各种 I/O 引擎
  • bs,表示 I/O 的大小。默认值是4KiB
  • filename,表示文件路径,可以是磁盘路径(测试磁盘性能),也可以是文件路径(测试文件系统性能)
  • size,寻址空间,IO会落在 [0, size)这个区间的硬盘空间上。这是一个可以影响IOPS的参数。一般设置为硬盘的大小

  • runtime,运行时间

  • numjobs,并行job数,默认1

  • group_reporting,聚合job的测试结果

四个核心磁盘IO性能指标

介绍完工具,我们来介绍一下IO的性能指标,工具只是直观的给出测试结果,对指标的解读才是评估IO性能的依据,磁盘I/O的核心指标包括,

使用率,是指磁盘忙处理 I/O 请求的百分比

IOPS(Input/Output Per Second),是指每秒的 I/O 请求数

吞吐量,是指每秒的 I/O 请求大小

响应时间,是指从发出 I/O 请求到收到响应的间隔时间

如果孤立的看通过工具得来的指标数据是没有意义的,也就是说一定要结合场景及硬件特性来观测指标数据,如我的测试环境金士顿NVME SSD盘(下图截自金士顿官网)明确标出读/写速度3500MB/秒和2100MB/秒(MB=10^6)

先来一个read测试


  1. # fio job文件nread.fio
  2. root@nvme:~/fio# cat nread.fio
  3. [global]
  4. bs=4096
  5. rw=read
  6. ioengine=libaio
  7. size=50G
  8. direct=1
  9. iodepth=256
  10. iodepth_batch=128
  11. iodepth_low=128
  12. iodepth_batch_complete=128
  13. userspace_reap
  14. group_reporting
  15. [test]
  16. numjobs=1
  17. filename=/dev/nvme0n1
  18. # 执行测试及输出结果
  19. root@nvme:~/fio# fio nread.fio
  20. test: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=256
  21. fio-3.28
  22. Starting 1 process
  23. Jobs: 1 (f=1): [R(1)][100.0%][r=2908MiB/s][r=744k IOPS][eta 00m:00s]
  24. test: (groupid=0, jobs=1): err= 0: pid=1509: Wed May 10 12:54:46 2023
  25. read: IOPS=728k, BW=2842MiB/s (2980MB/s)(50.0GiB/18015msec)
  26. slat (usec): min=70, max=856, avg=91.24, stdev= 9.05
  27. clat (usec): min=60, max=20044, avg=247.35, stdev=100.53
  28. lat (usec): min=159, max=20901, avg=338.61, stdev=102.93
  29. clat percentiles (usec):
  30. | 1.00th=[ 149], 5.00th=[ 194], 10.00th=[ 200], 20.00th=[ 212],
  31. | 30.00th=[ 225], 40.00th=[ 231], 50.00th=[ 237], 60.00th=[ 245],
  32. | 70.00th=[ 258], 80.00th=[ 273], 90.00th=[ 302], 95.00th=[ 347],
  33. | 99.00th=[ 433], 99.50th=[ 457], 99.90th=[ 537], 99.95th=[ 570],
  34. | 99.99th=[ 668]
  35. bw ( MiB/s): min= 2383, max= 2914, per=100.00%, avg=2843.14, stdev=134.15, samples=36
  36. iops : min=610048, max=745984, avg=727843.56, stdev=34342.08, samples=36
  37. lat (usec) : 100=0.14%, 250=64.34%, 500=35.33%, 750=0.19%, 1000=0.01%
  38. lat (msec) : 20=0.01%, 50=0.01%
  39. cpu : usr=12.67%, sys=54.62%, ctx=114337, majf=0, minf=268
  40. IO depths : 1=0.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=100.0%
  41. submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=100.0%
  42. complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=100.0%
  43. issued rwts: total=13107200,0,0,0 short=0,0,0,0 dropped=0,0,0,0
  44. latency : target=0, window=0, percentile=100.00%, depth=256
  45. Run status group 0 (all jobs):
  46. READ: bw=2842MiB/s (2980MB/s), 2842MiB/s-2842MiB/s (2980MB/s-2980MB/s), io=50.0GiB (53.7GB), run=18015-18015msec
  47. Disk stats (read/write):
  48. nvme0n1: ios=203471/0, merge=12818862/0, ticks=54295/0, in_queue=54295, util=99.48%

测试结果分析,分别使用iodepth=256、128、64、32、16、8进行测试,iodepth=256、iodepth_batch=128、iodepth_low=128、iodepth_batch_complete=128这一组参数结果最好,顺序读吞吐量(BW)峰值接近3000MB,距离厂商3500MB/秒的读速率稍有差距,差距在哪里呢?Linux内核NVME驱动为了其通用性和冗长的IO栈,并不能完全发挥其硬件性能,所以当下如SPDK等绕过内核的用户态NVME驱动已成为高性能存储首选技术方案,后续spdk文章会结束相关内容

iodepth_batch(等同于iodepth_batch_submit),批次提交,默认1,即立即提交

iodepth_low(low water mark,队列低于此值时开始填充队列),默认等于iodepth,fio总是尝试保持IO队列状态为满

iodepth_batch_complete(等同于iodepth_batch_complete_min),默认1,即有完成IO立即处理,该参数可以reduce latency

这几个参数对结果影响很大,详见man fio

除了iops、BW、latency几个主要IO指标外,需要注意latency的min、max、stdev数据,如果数据相对离散也就是stdev值异常,说明IO性能有可能出现长尾,此外还应该注意clat percentiles累积直方图数据,关于累积直方图,可以参考Promethues的HISTOGRAMS AND SUMMARIES

IO队列

fio测试,iodepth相关几个参数对测试结果影响非常明显,256为什么会稳定好于128,128则稳定好于64呢?


  1. root@nvme:~# lsscsi -lll
  2. [1:0:0:0] disk ATA ST2000DM008-2FR1 0001 /dev/sda
  3. device_blocked=0
  4. iocounterbits=32
  5. iodone_cnt=0x2d0b
  6. ioerr_cnt=0x25
  7. iorequest_cnt=0x2f1f
  8. queue_depth=32
  9. queue_type=simple
  10. scsi_level=6
  11. state=running
  12. timeout=30
  13. type=0
  14. [N:0:1:1] disk KINGSTON SNV2S1000G__1 /dev/nvme0n1
  15. capability=40
  16. ext_range=256
  17. hidden=0
  18. nsid=1
  19. range=0
  20. removable=0
  21. nr_requests=255
  22. read_ahead_kb=128
  23. write_cache=write back
  24. logical_block_size=512
  25. physical_block_size=512
  26. # 或通过sysfs查看nvme0n1 device的队列深度
  27. root@nvme:~/fio# cat /sys/devices/pci0000\:00/0000\:00\:1b.0/0000\:02\:00.0/nvme/nvme0/nvme0n1/queue/nr_requests
  28. 255
  29. root@nvme:~/fio#

无论是通过lsscsi -l还是通过sysfs查看,nvme0n1的队列深度是256,再次运行fio,同时打开iostat -x 2观测nvme设备队列相关指标数据


  1. Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
  2. loop5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
  3. nvme0n1 5286.00 1353216.00 333031.00 98.44 0.33 256.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.75 100.00
  4. sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

通过测试发现,当rw=read时,iostat输出rareq-sz几乎稳定等于256,而当rw=write时,wareq-sz稳定等于256,而增加iodepth至更大时fio和iostat指标数据都几乎无变化,但是减小时iops、BW等数据均会减少

通过SATA盘再次验证则数据变化不明显

另外,对于顺序读写,numjobs=1(IOPS=728k, BW=2842MiB/s)能够获得最好的收益(指标数据最好),numjobs增加时,指标数据会线性减少,当numjob=2(IOPS=393k, BW=1536MiB/s)、numjob=4(IOPS=400k, BW=1562MiB/s)、numjob=8(IOPS=366k, BW=1430MiB/s)

混合随机读写(读写比例80/20)

随机读写不同于顺序读写,混合随机读写场景更加贴近于真实场景,iops和BW都要小的多,测试如下,调整iodepth及numjobs测试结果见下表:


  1. [global]
  2. bs=4096
  3. rw=randrw
  4. rwmixwrite=20
  5. ioengine=libaio
  6. direct=1
  7. group_reporting
  8. iodepth=32
  9. iodepth_batch=8
  10. iodepth_low=8
  11. iodepth_batch_complete=8
  12. userspace_reap
  13. runtime=60
  14. [test]
  15. numjobs=16
  16. filename=/dev/nvme0n1
iodepth/_low/_batch/_complete numjobs iops(read) bw(read) iops(write) bw(write)
16/8/8/8 8 23.8k 93.1MiB/s 5968 23.3MiB/s
32/8/8/8 1 15.4k 60.3MiB/s 3865 15.1MiB/s
32/8/8/8 8 37.9k 148MiB/s 9500 37.1MiB/s
32/8/8/8 16 40.4k 158MiB/s 10.1k 39.5MiB/s
32/16/16/16 16 40.5k 158MiB/s 10.1k 39.5MiB/s
64/32/32/32 16 40.4k 158MiB/s 10.1k 39.5MiB/s
64/16/16/16 1 22.6k 88.4MiB/s 5660 22.1MiB/s
64/16/16/16 64 42.8k 167MiB/s 10.7k 41.8MiB/s

numjobs增加不是免费的,top观测fio所占物理内存线性增加,而最后numjobs=64 iodepth=64测试,综合iostat数据,w_await、r_await、aqu_sz都明显增加,混合随机读写场景下,相比于iodepth,numjobs更能影响IO性能

欢迎转载,请说明出处

文章知识点与官方知识档案匹配,可进一步学习相关知识
云原生入门技能树首页概览12637 人正在系统学习中

[转帖]​Linux开源存储漫谈(2)IO性能测试利器fio的更多相关文章

  1. 转载: 一、linux cpu、内存、IO、网络的测试工具

    来源地址: http://blog.csdn.net/wenwenxiong/article/details/77197997 记录一下 以后好找.. 一.linux cpu.内存.IO.网络的测试工 ...

  2. linux性能优化cpu 磁盘IO MEM

    系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长期和持续的过程,不 是说现在优化了,测试了,以后就可以一劳永逸了,也不是说书本上 ...

  3. 在linux系统中跟踪高IO等待

    原文作者:Jon Buys 原文地址:http://ostatic.com/blog/tracking-down-high-io-wait-in-linux 译者:Younger Liu,本作品采用知 ...

  4. Linux开源监控平台归总

    Linux开源监控平台归总 Cacti 偏向于基础监控.成图非常漂亮,需要php环境支持,并且需要mysql作为数据存储 Cacti是一个性能广泛的图表和趋势分析工具,可以用来跟踪并几乎可以绘制出任何 ...

  5. Ceph与Gluster之开源存储的对比

    一.Ceph与Gluster之开源存储的对比 一.Ceph与Gluster的原理对比 Ceph和Gluster是Red Hat旗下的成熟的开源存储产品,Ceph与Gluster在原理上有着本质上的不同 ...

  6. Gluster vs Ceph:开源存储领域的正面较量

    https://www.oschina.net/news/49048/gluster-vs-ceph 引言:开源存储软件Ceph和Gluster能够提供相似的特性并且能够为用户节省不小的开支.那么谁更 ...

  7. Linux 中的五种 IO 模型

    Linux 中的五种 IO 模型 在正式开始讲Linux IO模型前,比如:同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一 ...

  8. 你需要知道的MySQL开源存储引擎TokuDB

    在四月份的Percona Live MySQL会议上, TokuDB庆祝自己成为开源存储引擎整一周年.我现在仍能记得一年前它刚创建时的官方声明与对它的期望.当时的情况非常有意思,因为它拥有帮助MySQ ...

  9. arm驱动linux异步通知与异步IO【转】

    转自:http://blog.csdn.net/chinazhangzhong123/article/details/51638793 <[ arm驱动] linux异步通知与 异步IO> ...

  10. 截取linux文件存储路径方法

    1.截取linux文件存储路径方法 package com.tydic.eshop.action.freemarker; public class dddd { public static void ...

随机推荐

  1. 大数据实践解析(上):聊一聊spark的文件组织方式

    摘要: 在大数据/数据库领域,数据的存储格式直接影响着系统的读写性能.Spark针对不同的用户/开发者,支持了多种数据文件存储方式.本文的内容主要来自于Spark AI Summit 2019中的一个 ...

  2. LiteOS内核源码分析:消息队列Queue

    摘要:本文通过分析LiteOS队列模块的源码,掌握队列使用上的差异. 队列(Queue)是一种常用于任务间通信的数据结构.任务能够从队列里面读取消息,当队列中的消息为空时,挂起读取任务:当队列中有新消 ...

  3. 华为云GaussDB:发挥生态优势,培养应用型DBA

    摘要:GaussDB首要的任务是解决华为的业务连续性的需求,同时也是要确保使用GaussDB的客户的业务能够连续,所以我们坚持战略投入,坚持从每一行代码,坚持从生态开始来构建整个数据库体系. 本文分享 ...

  4. APP安全加固怎么做?加固技术、加固方法、加固方案

    ​ 前面的文章中我们为大家介绍了移动应用安全检测的测试依据.测试方法.和测试内容,本文我们着重分享App安全加固的相关内容. ​ (安全检测内容) 通过前面的文章我们知道了app安全检测要去检测哪些内 ...

  5. Solon Aop 特色开发(2)注入或手动获取Bean

    Solon,更小.更快.更自由!本系列专门介绍Solon Aop方面的特色: <Solon Aop 特色开发(1)注入或手动获取配置> <Solon Aop 特色开发(2)注入或手动 ...

  6. CentOS 硬盘扩容

    首先在虚机内将硬盘空间扩大,Hyper-V 需要将检查点删除 查看物理卷和卷组,并将物理卷加入到卷组 lvextend -l +100%FREE /dev/centos/root    #将剩余空间添 ...

  7. web自动化-selenium携带cookie免密登录

    在我们做web自动化的时候,经常会遇到含有登录的页面,我们必须登录之后才能够对我们想要操作的页面元素进行定位,也就是说所有的操作都在登录前提下,其实没必要每次请求都先登录,当我们登录成功了,会在coo ...

  8. 【论文笔记#1】SPGAN-DA:用于领域自适应遥感图像语义分割的语义保留生成对抗网络

    作者: Yansheng Li 发表年代: 2023 使用的方法: 无监督领域自适应(UDA).GAN.ClassMix.边界增强 来源: IEEE TGRS 方向: 语义分割 期刊层次: CCF B ...

  9. 6行代码!用Python将PDF转为word

    pdf转word应该算是一个很常见的需求了 网上有些免费的转换工具,一方面不安全,有文件泄露风险,另一方面有免费转换的次数限制. 今天向大家分享一个很好用的工具:pdf2docx 安装 $ pip i ...

  10. 复旦大学2020考研机试题-编程能力摸底试题(A-E)

    A.斗牛 给定五个0~9范围内的整数a1,a2,a3,a4,a5.如果能从五个整数中选出三个并且这三个整数的和为10的倍数(包括0),那么这五个整数的权值即为剩下两个没被选出来的整数的和对10取余的结 ...