FIO性能测试实战:从参数解析到云盘性能优化

📅 发布时间:2026/7/9 22:49:54 👁️ 浏览次数:
FIO性能测试实战:从参数解析到云盘性能优化
1. 为什么你需要掌握FIO不只是跑个分那么简单如果你在云上部署过数据库或者搭建过文件服务器肯定遇到过这样的困惑明明买的是宣称“高性能”的云盘为什么实际用起来感觉还是慢是应用配置不对还是云服务商“虚标”了性能我当年第一次遇到这种问题时也是一头雾水直到我系统性地用FIO工具把云盘的“底裤”扒了个干净才真正搞明白问题出在哪里。FIO全称Flexible I/O Tester是Linux系统下最强大、最灵活的磁盘性能测试工具没有之一。它不像一些图形化工具那样简单点几下就出结果而是给了你一把“手术刀”让你可以精确地模拟出任何你想要的I/O负载模式——无论是数据库的随机小块读写还是视频流服务的大文件顺序读写都能模拟得惟妙惟肖。很多人把FIO测试简单地理解为“跑个分”看看IOPS和带宽的数字这其实只看到了冰山一角。真正的价值在于通过设计不同的测试用例你可以精准地定位性能瓶颈。比如你的应用在高峰期响应变慢是IOPS不够用了还是吞吐量带宽达到了上限是读写延迟Latency太高还是队列深度Queue Depth没调优这些问题的答案都能通过一组精心设计的FIO测试找出来。更重要的是当你掌握了FIO你就拥有了和云服务商“对话”的能力。你可以用测试数据证明当前云盘的性能是否达到了产品规格书的承诺为扩容或更换更高性能的云盘提供铁证。接下来我就带你从零开始彻底搞懂FIO的核心参数并针对主流云服务商的云盘给出实战优化策略。2. 吃透FIO核心参数你的测试为何不准直接照搬网上的FIO命令就跑结果往往不尽人意因为你不理解每个参数背后的“脾气”。FIO的参数众多但核心的就那么几个理解了它们你就能自己组合出任何测试场景。咱们一个一个来拆解我会结合我踩过的坑告诉你哪些参数最容易让人误解。2.1 读写模式与I/O引擎同步还是异步-rw参数定义了读写模式这是测试的“剧本”。read/write是顺序读写模拟拷贝大文件randread/randwrite是随机读写模拟数据库操作randrw则是混合读写更贴近真实业务。这里有个关键点顺序和随机性能天差地别。一块普通的SATA SSD顺序读写能跑到500MB/s但4K随机写可能只有几万IOPS约合几十MB/s。所以测试前一定要想清楚你的业务场景。-ioengine参数决定了FIO如何与磁盘“对话”。最常用的是libaioLinux native asynchronous I/O。我强烈建议你永远在测试云盘时使用libaio。为什么因为现代应用和操作系统为了榨干硬件性能普遍采用异步I/O。同步I/O如sync,psync一次只能发一个请求等磁盘处理完才发下一个这完全无法发挥出云盘尤其是那些高IOPS云盘如阿里云ESSD、华为云超高IO的并发能力。libaio可以一次性提交一大批I/O请求由-iodepth控制让磁盘队列始终保持忙碌这才是真实的压力测试。我见过不少人在测试高队列深度时还用同步引擎结果测出来的性能惨不忍睹还以为是盘有问题其实只是测试方法不对。2.2 队列深度与并发数压满磁盘的关键-iodepthI/O队列深度和-numjobs并发任务数是决定测试压力的两个核心杠杆。你可以把它们想象成高速公路的“车道数”和“车队数量”。-iodepth指的是每个线程或进程能同时向磁盘“喊话”的请求数量。对于云盘尤其是支持高并发的NVMe SSD云盘这个值必须设得足够大才能测出其极限性能。阿里云官方文档测试ESSD云盘IOPS时队列深度通常设置为128。但要注意不是所有场景都适合高队列深度。测试**延迟Latency**时恰恰需要把-iodepth设为1这样才能测出单个I/O请求的响应时间模拟轻负载场景。-numjobs就是同时运行多少个这样的测试线程。总并发数 iodepth * numjobs。如果你想模拟一个多线程应用比如一个MySQL数据库连接池有16个连接访问磁盘的场景就可以设置-numjobs16同时配合适当的-iodepth。我个人的经验是对于常规性能摸底可以先从-numjobs1和-iodepth32或64开始观察磁盘利用率。如果util磁盘利用率达不到100%说明压力不够可以逐步增加numjobs。这里有个大坑-iodepth和-numjobs的增加会线性增加系统内存占用。因为每个未完成的I/O请求都需要内存来保存其状态和数据。如果你在测试一个非常大的size比如1TB时把并发开得很大可能会把系统内存耗尽导致测试中断甚至系统卡死。所以测试数据量-size和并发级别需要平衡。对于快速测试-size10G或-size20G通常就够了关键是保证测试时间-runtime足够长比如60秒以上让性能曲线稳定下来。2.3 块大小与测试目标IOPS、带宽与延迟的博弈-bsblock size块大小是另一个灵魂参数它直接决定了你测试的是哪个性能指标。4K随机读写是IOPS的“考场”而1M顺序读写是吞吐量带宽的“跑道”。测试IOPS使用-bs4k或-bs8k配合-rwrandread或-rwrandwrite。云服务商宣称的IOPS如50,000 IOPS通常就是在4KB随机读写的条件下测得的。记住块越小每秒能完成的操作次数IOPS理论上限就越高但对延迟更敏感。测试吞吐量Throughput/Bandwidth使用-bs128k、-bs256k甚至-bs1m配合-rwread或-rwwrite。这模拟的是大文件连续传输的场景结果单位通常是 MB/s。很多对象存储或视频处理业务更关心这个指标。测试延迟Latency使用-bs4k但必须将-iodepth1并且通常-numjobs1。这样排除了队列带来的干扰测出的延迟报告中lat或clat指标才是单个I/O请求的真实响应时间单位是微秒us或毫秒ms。数据库OLTP业务对这个指标极其敏感。-direct1这个参数务必加上。它表示绕过操作系统的页面缓存Page Cache直接对磁盘进行读写。如果不加你的读写可能会命中内存缓存测出来的速度飞快但那只是内存的速度不是磁盘的真实性能这个结果毫无参考价值。只有在极少数你想测试文件系统缓存效果的场景下才会设置-direct0。3. 实战手把手测试阿里云与华为云云盘理论说再多不如动手跑一遍。下面我以最常见的场景——测试一块新挂载的数据盘为例演示完整流程。警告以下测试会直接读写裸设备/dev/vdX会破坏该设备上所有数据请务必确认你操作的是正确的、全新的、或无数据的数据盘对系统盘通常是 /dev/vda千万不要测试3.1 环境准备与安全确认第一步连接上你的云服务器。然后我们需要找到要测试的磁盘设备名。使用lsblk或fdisk -l命令查看。假设我们找到一块未使用的数据盘叫/dev/vdb。# 查看块设备信息确认磁盘大小和是否已有分区 sudo fdisk -l /dev/vdb如果输出显示该磁盘没有分区表比如提示“Disk /dev/vdb doesn‘t contain a valid partition table”那就对了我们可以直接测试裸盘。如果这块盘已经有分区或文件系统并且里面有重要数据请立刻停止你可以选择用mkfs命令在测试前格式化一个空盘或者联系云服务商挂载一块全新的空数据盘来测试。接着安装FIO和必要的库。在CentOS/Alibaba Cloud Linux上sudo yum install libaio libaio-devel fio -y在Ubuntu/Debian上sudo apt-get update sudo apt-get install libaio1 libaio-dev fio -y3.2 四大经典测试用例与结果解读安装好后我们就可以开始跑了。我准备了四组最核心的测试命令分别对应随机写、随机读、顺序写、顺序读。我们创建一个测试脚本run_fio_test.sh方便多次执行。#!/bin/bash DEVICE/dev/vdb # 请修改为你的实际设备名 SIZE10G # 测试数据量建议至少是内存的两倍 RUNTIME60 # 测试时间秒 echo 开始FIO性能测试设备: $DEVICE # 1. 随机写 (测试写IOPS和写延迟) echo 1. 测试随机写IOPS... sudo fio -filename$DEVICE -direct1 -iodepth128 -rwrandwrite -ioenginelibaio -bs4k -size$SIZE -numjobs1 -runtime$RUNTIME -group_reporting -namerandwrite_test # 2. 随机读 (测试读IOPS和读延迟) echo 2. 测试随机读IOPS... sudo fio -filename$DEVICE -direct1 -iodepth128 -rwrandread -ioenginelibaio -bs4k -size$SIZE -numjobs1 -runtime$RUNTIME -group_reporting -namerandread_test # 3. 顺序写 (测试写吞吐量) echo 3. 测试顺序写吞吐量... sudo fio -filename$DEVICE -direct1 -iodepth64 -rwwrite -ioenginelibaio -bs1024k -size$SIZE -numjobs1 -runtime$RUNTIME -group_reporting -namewrite_bw_test # 4. 顺序读 (测试读吞吐量) echo 4. 测试顺序读吞吐量... sudo fio -filename$DEVICE -direct1 -iodepth64 -rwread -ioenginelibaio -bs1024k -size$SIZE -numjobs1 -runtime$RUNTIME -group_reporting -nameread_bw_test echo 基础测试完成 给脚本执行权限并运行chmod x run_fio_test.sh sudo ./run_fio_test.sh。跑完后你会看到大段的输出关键信息在最后面的总结部分。我们以一段随机写的输出为例来解读randwrite_test: (groupid0, jobs1): err 0: pid12345: Thu Jan 1 00:00:00 2024 write: io10240MB, bw175367KB/s, iops43841, runt 60001msec clat (usec): min90, max16200, avg2850.12, stdev1200.33 lat (usec): min90, max16200, avg2850.45, stdev1200.33 clat percentiles (usec): | 1.00th[ 1200], 5.00th[ 1400], 10.00th[ 1600], 20.00th[ 1800], | 30.00th[ 2000], 40.00th[ 2200], 50.00th[ 2400], 60.00th[ 2700], | 70.00th[ 3200], 80.00th[ 3800], 90.00th[ 4800], 95.00th[ 5600], | 99.00th[ 7200], 99.50th[ 8000], 99.90th[10000], 99.95th[11000], | 99.99th[14000]bw175367KB/s这是带宽约171 MB/s。对于顺序读写测试这个值更重要。iops43841这就是我们最关心的IOPS每秒4.3万次写操作。对比你购买的云盘规格看是否达标。clat (usec): avg2850.12这是完成延迟的平均值2850微秒即2.85毫秒。这个值越小越好。对于延迟敏感型应用你还需要关注百分位延迟比如99.00th[7200]表示99%的请求延迟在7.2毫秒以内。如果99.9%的延迟突然飙得很高说明磁盘性能可能不稳定。3.3 进阶混合读写与延迟专项测试真实的业务很少是100%纯读或纯写。数据库通常是读多写少我们可以用-rwrandrw -rwmixread70来模拟70%读、30%写的混合负载。# 混合随机读写测试 (70%读30%写) sudo fio -filename$DEVICE -direct1 -iodepth128 -rwrandrw -rwmixread70 -ioenginelibaio -bs4k -size$SIZE -numjobs4 -runtime$RUNTIME -group_reporting -namerandrw_mix_test注意这里我加了-numjobs4模拟4个并发客户端。测试结果会分别给出读和写的IOPS、带宽和延迟非常具有参考价值。对于数据库等对延迟要求极高的场景专项延迟测试必不可少# 随机写延迟测试 (队列深度为1是关键) sudo fio -filename$DEVICE -direct1 -iodepth1 -rwrandwrite -ioenginelibaio -bs4k -size1G -numjobs1 -group_reporting -namerandwrite_latency_test # 随机读延迟测试 sudo fio -filename$DEVICE -direct1 -iodepth1 -rwrandread -ioenginelibaio -bs4k -size1G -numjobs1 -group_reporting -namerandread_latency_test这里我把-size调小到1G因为队列深度为1时速度不会很快测试很快能完成。重点关注输出中的clat avg和99.00th之后的百分位延迟。一个健康的云盘平均延迟应该在1毫秒以内99%的延迟在几毫秒内。4. 云盘性能优化实战从测试数据到调优策略拿到测试数据只是第一步如何解读并据此优化才是真功夫。不同云服务商的云盘特性不同优化策略也略有差异。我们以阿里云ESSD云盘和华为云超高IO云盘为例来分析。4.1 诊断性能瓶颈看懂你的测试报告当你发现测试结果不理想时别急着找云厂商“撕”先按以下步骤自查CPU或内存成为瓶颈了吗在测试时用top或htop命令观察%waI/O等待和%id空闲。如果%wa一直很高比如超过30%而CPU空闲很多那瓶颈确实在磁盘。如果某个CPU核心的%sys或%usr很高可能是FIO本身或内核处理I/O的开销过大可以尝试降低numjobs。队列深度用对了吗测试高IOPS时iodepth必须足够大。对于阿里云ESSD PL1及以上规格官方建议用128甚至256来压测极限IOPS。如果你用iodepth1去测IOPS结果当然很低但这不代表盘不行只代表它不适合高并发场景。块大小匹配业务吗你用bs1m测出来的IOPS很低是正常的因为一个I/O请求就处理1MB数据物理上需要更多时间。反过来你用bs4k测出来的带宽MB/s不高也正常。一定要根据业务实际I/O大小来选择bs。实例规格拖后腿了吗这一点很多人忽略。云盘的性能发挥依赖于它所挂载的ECS实例。如果实例本身规格太低比如是共享型或入门级计算型其CPU处理能力和网络/总线带宽可能无法支撑高端云盘的全速运行。特别是对于像阿里云ESSD PL-X这类数百万IOPS的“怪兽”级云盘必须搭配8核以上、网络增强型等高规格实例才能发挥全力。4.2 阿里云ESSD云盘调优要点阿里云的ESSDEnhanced SSD是目前的主流高性能云盘它有一个核心概念性能级别PL。PL0/1/2/3分别对应不同的基线IOPS/吞吐量和突发能力。优化要点如下开启多队列Multi-Queue对于支持NVMe协议的ESSD云盘通常是PL2/PL3或部分新型号确保在操作系统中启用了多队列。检查命令ls /sys/block/vd*/queue/nr_requests。如果看到数值大于1比如128说明已启用。这能大幅提升高并发下的IOPS。匹配实例与云盘性能在阿里云控制台挂载云盘时系统会提示“性能突发”或“已开启多队列”等信息。务必为高性能PL云盘选择推荐的高规格实例族如计算型c7、通用型g7、内存型r7等。利用性能监控阿里云云监控提供了详细的云盘读/写IOPS、读/写吞吐量、读/写延迟等指标。将你的FIO测试结果与监控面板上的实时数据对比看是否达到上限。如果监控显示读写吞吐量或IOPS已经长时间顶到规格上限那扩容或升级云盘PL等级就是最直接的优化。4.3 华为云超高IO云盘调优要点华为云的超高IO云盘类似产品同样性能强劲其优化思路与阿里云有共通之处但也有细微差别关注IO调度器在Linux内核中I/O调度器如mq-deadline,kyber,none对性能尤其是延迟有影响。对于NVMe SSD通常建议将调度器设置为none即Noop调度器以减少内核层面的调度开销。使用命令cat /sys/block/vdb/queue/scheduler查看当前调度器使用echo ‘none’ /sys/block/vdb/queue/scheduler进行修改将vdb换成你的设备名。文件系统与挂载参数如果是在云盘上创建文件系统后测试-filename指定为文件路径而非设备那么文件系统类型和挂载参数就至关重要。对于XFS或EXT4建议启用noatime,nodiratime挂载选项减少不必要的元数据更新。对于数据库等大量小文件场景可以适当调整inode大小和数量。内核参数微调对于极端性能追求可以调整一些内核参数如vm.dirty_ratio,vm.dirty_background_ratio控制脏页回写策略以及vm.swappiness控制交换倾向。但调整这些参数需要非常谨慎最好在测试环境验证后再上生产。一个错误的设置可能导致系统不稳定。4.4 通用优化清单与避坑指南无论用哪家云以下这些通用建议都能帮你提升磁盘I/O表现对齐I/O确保文件系统分区、数据库表空间等的起始位置与云盘的物理扇区通常是4KB或更大对齐。现代工具如fdisk的-usectors和-o start和文件系统如mkfs.xfs或mkfs.ext4默认都会对齐但自己手动分区时仍需留意。避免测试干扰在测试时确保没有其他重要进程在大量读写磁盘。可以用iotop命令查看实时磁盘活动。最好在刚启动的、业务负载为零的实例上进行测试。理解“突发”与“基线”很多云盘如阿里云ESSD PL0/PL1华为云通用型SSD都有性能突发Burst能力。FIO短时间如30秒测试可能会享受到突发的高性能但长时间如10分钟测试结果会回落到基线水平。设计测试时-runtime应足够长如300秒以观察性能是否稳定。多次测试取平均值磁盘性能受宿主机负载、网络抖动等因素影响单次测试可能有波动。建议每个测试场景跑3-5次取平均值和相对稳定的结果作为参考。最后我把最常用的几组FIO命令做成了一个快速参考表你可以保存下来根据你的云盘类型和测试目标直接取用测试目标核心参数组合示例适用场景与解读极限随机写IOPS-rwrandwrite -bs4k -iodepth128 -numjobs4测试云盘写密集型负载极限如数据库重做日志。对比云盘规格中的“最大随机写IOPS”。极限随机读IOPS-rwrandread -bs4k -iodepth128 -numjobs4测试云盘读密集型负载极限如数据库查询。对比“最大随机读IOPS”。顺序写吞吐量-rwwrite -bs1024k -iodepth64 -numjobs1测试大文件连续写入速度如备份、视频写入。关注bw(带宽)。顺序读吞吐量-rwread -bs1024k -iodepth64 -numjobs1测试大文件连续读取速度如视频播放、数据分析。关注bw。读写延迟关键-rwrandwrite/randread -bs4k -iodepth1 -numjobs1测试单次请求响应时间对数据库至关重要。关注clat avg及99.00th延迟。混合读写压力-rwrandrw -rwmixread70 -bs8k -iodepth32 -numjobs8模拟真实生产负载如70%读30%写综合评估性能。掌握FIO就像是拿到了存储性能领域的“听诊器”和“手术刀”。它不能直接解决性能问题但能帮你精准地定位问题根源——到底是云盘性能不足还是应用配置不当或是实例规格成了瓶颈。下次当你对云盘性能有疑虑时别再凭感觉跑一组FIO测试让数据说话。从参数解析到实战优化这条路我走过希望我的经验能让你少踩些坑。