尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Linux磁盘性能测试全攻略:从dd到fio,精准评估IOPS与延迟

Linux磁盘性能测试全攻略:从dd到fio,精准评估IOPS与延迟 1. 项目概述为什么需要测试磁盘读写速度在Linux服务器运维、性能调优或者日常开发中磁盘I/O性能往往是整个系统中最容易被忽视却又至关重要的瓶颈。你可能遇到过这样的情况数据库查询突然变慢应用响应时间拉长甚至系统出现卡顿排查了一圈CPU和内存都正常最后发现是磁盘“拖了后腿”。这时候一个准确的磁盘读写速度测试就是定位问题的“听诊器”。“如何测试Linux磁盘的读写速度”这个标题背后指向的是一个非常实际且高频的需求。它不仅仅是运行一个命令那么简单而是涉及到测试方法的选择、测试参数的解读、测试结果的对比分析以及如何将测试数据转化为优化决策。无论是评估新采购的SSD是否达到标称性能还是排查生产环境中的I/O瓶颈亦或是为数据库、虚拟化等I/O密集型应用规划存储方案掌握一套可靠的磁盘测速方法论都是基本功。我自己在多年的运维和架构工作中无数次通过磁盘测速来验证硬件性能、诊断线上问题。我发现很多朋友只知道用dd命令但测出来的结果往往和实际体验相差甚远或者看不懂hdparm、fio这些更专业工具的输出。这篇文章我就来系统性地拆解一下在Linux环境下测试磁盘读写速度的完整流程、工具选型背后的逻辑以及如何避开那些常见的“坑”让你拿到真正有参考价值的性能数据。2. 核心工具选型与适用场景解析测试磁盘速度工具的选择直接决定了结果的准确性和场景的匹配度。没有“银弹”工具不同的工具适用于不同的测试目的。下面这张表清晰地对比了最常用的几款工具工具名称测试类型主要特点适用场景不适用场景dd顺序读写系统自带简单粗暴。通过拷贝大文件来测试连续I/O。快速验证磁盘大文件连续读写能力例如备份、视频流处理。测试随机I/O、IOPS、队列深度等复杂场景结果受缓存影响极大。hdparm顺序读缓存/直接专门用于ATA/IDE/SATA硬盘的工具能测试带缓存和直接读的速度。快速评估硬盘尤其是机械硬盘的原始顺序读取性能。测试写性能对NVMe SSD支持有限测试随机I/O。fio(Flexible I/O Tester)全场景顺序/随机读/写同步/异步功能极其强大的专业级I/O基准测试工具可模拟任何I/O负载。数据库、虚拟化、文件服务器等生产环境性能评估与瓶颈定位压测。命令行参数复杂对新手不友好需要较长时间运行。ioping延迟Latency类似于网络ping专注于测试磁盘I/O的响应延迟。评估磁盘的响应速度对于数据库、交易系统等延迟敏感型应用至关重要。测试吞吐量Throughput和IOPS。注意dd命令虽然方便但它最大的问题是会利用操作系统的页面缓存Page Cache。如果你写一个文件然后立刻读数据可能还在内存里测出来的速度是内存速度而不是真实的磁盘速度。这在评估真实性能时是一个巨大的误导。为什么我强烈推荐掌握fio因为真实世界的负载很少是纯粹的顺序读写。一个数据库服务器既有顺序写日志Redo Log也有大量的随机读索引和数据页。一个Web服务器可能同时服务许多小文件的随机读请求。fio的强大之处在于它能精确模拟这些混合负载给出包括IOPS每秒输入输出操作数、带宽Bandwidth、延迟Latency在内的完整性能画像。这对于容量规划和性能调优来说是dd和hdparm无法替代的。3. 实战操作从基础命令到专业压测了解了工具我们进入实战环节。我会从最简单的命令开始逐步深入到复杂的场景模拟。3.1 快速上手使用dd和hdparm进行初步评估当你需要快速对磁盘的连续读写能力有个大致了解时这两个命令是首选。使用dd测试写入速度# 测试写入速度生成一个1GB的文件观察耗时 dd if/dev/zero of./testfile bs1M count1024 oflagdirect convfdatasync命令拆解if/dev/zero: 从“零设备”读取数据提供无限的空字节流避免数据源成为瓶颈。of./testfile: 输出到当前目录的testfile文件。bs1M: 设置每次读写的数据块大小为1MB。更大的块通常能获得更高的吞吐量。count1024: 读写1024个块总共1GB1024 * 1MB。oflagdirect:关键参数。使用直接I/ODirect I/O绕过操作系统的缓冲区缓存Buffer Cache让数据直接写入磁盘。这是获得真实写入速度的关键。convfdatasync:另一个关键参数。在命令结束前强制将文件数据和元数据同步到磁盘。确保所有数据都落盘后才结束计时否则dd可能在数据还在缓存时就报告完成导致速度虚高。结果解读命令执行完毕后会输出类似1073741824 bytes (1.1 GB, 1.0 GiB) copied, 5.12345 s, 210 MB/s的信息。这里的210 MB/s就是测得的平均写入速度。使用dd测试读取速度# 首先确保有测试文件如刚才生成的testfile然后清空缓存再测试读速度 sudo sh -c echo 3 /proc/sys/vm/drop_caches # 清除页面缓存、目录项和inode缓存 dd if./testfile of/dev/null bs1M count1024 iflagdirectiflagdirect: 同样使用直接I/O读取绕过缓存。清空缓存测试读取前清除系统缓存至关重要否则测出的可能是内存速度。使用hdparm测试读取速度# 查看磁盘信息并测试带缓存读 sudo hdparm -I /dev/sda | grep -i model # 查看磁盘型号 sudo hdparm -Tt /dev/sda-T: 测试缓存Buffer Cache的读取速度。这基本是内存的速度用于评估系统内存和总线的性能。-t: 测试设备磁盘的直接读取速度会绕过缓存。这个数字更接近磁盘的真实顺序读取性能。结果会分别显示Timing cached reads和Timing buffered disk reads的速度。3.2 专业评估使用fio进行全方位压测fio的配置通常写在一个 job file任务文件里这样参数清晰且可重复使用。下面我们创建一个基础的测试文件。安装 fio大多数Linux发行版都可以通过包管理器安装。# Ubuntu/Debian sudo apt-get install fio # CentOS/RHEL sudo yum install fio创建并运行一个综合测试任务新建一个文件例如disk_test.fio内容如下[global] ioenginelibaio # 使用Linux原生异步I/O引擎效率最高 direct1 # 使用直接I/O绕过缓存 size1G # 每个线程/进程使用的文件大小 runtime30 # 每个测试项目运行时间秒 directory/mnt/test # 测试目录请替换为你的测试挂载点 filename_formatfio_test.$jobname.$filenum [seq_write] name顺序写测试 rwwrite bs1M iodepth1 [seq_read] name顺序读测试 rwread bs1M iodepth1 [rand_write_4k] name4K随机写测试 rwrandwrite bs4k iodepth32 # 提高队列深度以压测IOPS [rand_read_4k] name4K随机读测试 rwrandread bs4k iodepth32运行测试sudo fio disk_test.fio参数深度解析ioenginelibaio: Linux上性能最好的异步I/O引擎对于现代SSD和高速存储必须使用异步I/O才能发挥其队列能力。direct1: 和dd的oflagdirect作用一样确保测试的是真实的磁盘I/O。iodepth:队列深度。这是理解存储性能的核心概念。你可以把它想象成一条高速公路上的车道数。iodepth1意味着每次只发一个I/O请求等这个请求完成后再发下一个类似单车道。iodepth32意味着可以同时发出最多32个I/O请求类似32车道。对于NVMe SSD这种支持高并发的高性能设备提高队列深度是榨取其最大IOPS潜力的关键。但对于机械硬盘提高队列深度可能因磁头频繁寻道反而降低性能。bs:块大小。模拟不同的I/O模式。大块如1M测吞吐量带宽小块如4k测IOPS和延迟。数据库操作多以4K/8K/16K随机读写为主。rw: 定义了读写模式。write/read是顺序randwrite/randread是随机。结果解读fio的输出非常详细。你需要重点关注以下几行seq_write: (groupid0, jobs1): err 0: pid12345: ... write: IOPS105, BW105MiB/s (110MB/s), ... (运行时间等) iops : min 100, max 110, avg105.00, stdev 2.00 bw (MiB/s) : min 100, max 110, avg105.00, stdev 2.00IOPS: 每秒操作数。对于随机4K测试这个值越高越好直接反映了磁盘处理并发小请求的能力。BW (Bandwidth): 带宽即吞吐量。对于顺序读写测试这个值反映了磁盘传输大块数据的最大能力。lat (Latency): 延迟。包括clat完成延迟和slat提交延迟。clat分布如clat percentiles对于评估服务稳定性尤其重要它告诉你99%或99.9%的请求在多少毫秒内完成。数据库应用特别关注高百分位延迟如P99.9。3.3 延迟专项测试使用ioping对于延迟敏感型应用ioping能给你最直观的感受。# 安装ioping # Ubuntu/Debian: sudo apt-get install ioping # CentOS/RHEL: 可能需要从EPEL源安装或编译 # 测试当前目录的I/O延迟 ioping -c 10 .-c 10: 发送10次请求。 输出会显示每次请求的响应时间以及最小值、平均值、最大值。单位通常是微秒(us)或毫秒(ms)。一块好的NVMe SSD平均延迟可以低于100微秒而机械硬盘则在数毫秒到十几毫秒。4. 测试环境准备与关键注意事项测试结果的准确性一半取决于工具另一半取决于测试环境。不注意以下要点测试就失去了意义。4.1 测试前的环境准备清单选择正确的测试目标务必在独立的、未使用的磁盘或分区上进行测试。不要在系统盘尤其是根分区满负荷运行时测试系统自身的I/O会严重干扰结果。最好准备一块空白磁盘或新建一个分区。卸载并重新挂载可选但推荐对于要测试的文件系统可以先卸载umount再用-o discard针对SSD等选项重新挂载确保文件系统状态干净。避开缓存陷阱如前所述所有测试命令必须使用直接I/Odirect1,oflagdirect,iflagdirect来绕过操作系统缓存。对于读测试务必在测试前使用echo 3 /proc/sys/vm/drop_caches清空缓存。预热与稳态特别是对于SSD其性能可能在使用初期空盘和写入一段时间后稳态有差异。企业级测试通常要求先用fio进行长时间的预处理Preconditioning使磁盘达到稳定状态后再测试。消费级测试可以忽略此步但要知道空盘测出的速度可能是“最佳情况”。多跑几次取平均I/O性能存在波动单次测试可能有偶然性。对每个测试场景建议运行3-5次去掉异常值后取平均。4.2 理解你的存储设备机械硬盘 (HDD)性能受磁头寻道时间和旋转延迟限制。顺序读写尚可通常100-200 MB/s但随机IOPS非常低通常100-200。提高iodepth对提升其IOPS帮助不大反而可能因排队增加延迟。SATA SSD随机IOPS大幅提升数万到十万级顺序读写速度在500 MB/s左右受SATA 3.0接口6Gbps带宽限制。iodepth可以适当提高如32。NVMe SSD性能怪兽。随机IOPS可达数十万甚至百万级顺序读写超过3 GB/sPCIe 3.0 x4或7 GB/sPCIe 4.0 x4。必须使用高队列深度iodepth64, 128甚至256和多个工作线程numjobs才能压满其性能。使用libaio引擎。4.3 我的实操心得与避坑指南dd命令的“秒完”假象如果你用dd不加oflagdirect和convfdatasync会发现写入一个10GB的文件“秒完”速度显示几个GB/s。这绝对是假象数据只写到了内存缓存就返回了。永远记得加上这两个参数来获取真实的写入速度。测试文件大小要足够测试文件大小至少是系统内存的2-3倍才能确保数据不会完全被缓存。例如系统有16G内存测试文件最好用32G或更大。对于fio可以用size32G。关注延迟分布而不仅是平均值平均IOPS高固然好但如果延迟的P99.9最慢的0.1%的请求非常高意味着你的应用偶尔会遭遇“卡顿”。这对于在线交易系统是致命的。fio输出的clat percentiles一定要看。模拟真实负载不要只测顺序读写。根据你的应用场景设计测试。如果是MySQL数据库重点测试16k的随机读写和高队列深度。如果是Web服务器存放图片可以测试128k左右的顺序读和一定比例的随机读。小心“写放大”与性能衰减测试SSD特别是消费级TLC/QLC SSD的写入性能时长时间持续写入后速度可能会断崖式下降这是缓存用尽或触发了垃圾回收GC。你的测试时长runtime应该覆盖到应用可能遇到的长时写入场景。5. 结果分析与性能瓶颈定位拿到测试数据后如何分析这里提供一个简单的决策树顺序读写速度远低于预期例如NVMe SSD测出来只有1GB/s检查接口使用lspci | grep -i nvme或lsblk -d -o name,rota,size,model确认磁盘型号和接口。一块PCIe 4.0的SSD插在PCIe 3.0插槽上速度会减半。检查CPU占用使用top或iotop查看fio进程是否占满了一个CPU核心。单线程fio可能无法驱动高端SSD尝试增加numjobs并发任务数来充分利用多核CPU和SSD的多个队列。检查散热高性能SSD过热会触发降频保护。触摸散热片或使用sensors命令查看温度。随机读写IOPS低检查队列深度iodepth这是最常见的原因。对于NVMe SSD尝试将iodepth从1逐步提高到64、128。观察IOPS是否随之增长直到饱和。检查块大小bs确认测试的块大小是否符合你的场景。用1M块测不出高IOPS。检查I/O引擎确认使用了ioenginelibaio并且系统支持可能需要安装libaio库。延迟过高对比ioping结果如果ioping测出的基础延迟就很高可能是硬件问题或驱动问题。查看fio的clat延迟分布如果平均延迟低但P99.9延迟极高说明磁盘存在“卡顿”可能是固件问题、垃圾回收导致或者是共享存储网络中的干扰。检查系统负载在测试期间使用iostat -x 1观察磁盘的util利用率和await平均等待时间。如果util持续接近100%说明磁盘已是瓶颈。与标称值对比将你的测试结果顺序读/写、4K随机读/写IOPS与磁盘官网的标称值对比。在正确的测试条件下高队列深度、多线程、直接I/O结果应该能达到标称值的70%-90%以上。如果差距巨大就需要按上述步骤排查。6. 进阶场景与脚本化实践对于需要频繁测试或自动化集成的场景将测试过程脚本化是高效的做法。编写一个自动化测试脚本你可以创建一个Shell脚本自动执行清缓存、运行多种fio测试、并格式化输出关键结果。下面是一个简化示例的框架#!/bin/bash TEST_DIR/mnt/test # 修改为你的测试目录 OUTPUT_FILEdisk_benchmark_$(date %Y%m%d_%H%M%S).log echo 磁盘性能基准测试 $(date) | tee -a $OUTPUT_FILE echo 测试目录: $TEST_DIR | tee -a $OUTPUT_FILE echo | tee -a $OUTPUT_FILE # 1. 清空缓存 echo [1/5] 清空系统缓存... sudo sh -c echo 3 /proc/sys/vm/drop_caches # 2. 使用fio进行顺序读写测试 echo [2/5] 运行顺序读写测试... sudo fio --nameseq_write --rwwrite --bs1M --size1G --iodepth1 --ioenginelibaio --direct1 --directory$TEST_DIR --runtime30 --output-formatjson | jq .jobs[0].write.bw $OUTPUT_FILE # 类似地添加 seq_read, rand_write_4k, rand_read_4k 测试并使用jq解析JSON输出中的bw, iops, lat_ns.mean等字段 # 3. 使用ioping测试延迟 echo [5/5] 运行I/O延迟测试... ioping -c 100 $TEST_DIR | grep -E avg|min|max $OUTPUT_FILE echo | tee -a $OUTPUT_FILE echo 测试完成详细结果已保存至: $OUTPUT_FILE | tee -a $OUTPUT_FILE cat $OUTPUT_FILE这个脚本使用了fio的JSON输出格式并利用jq工具来精准提取我们关心的指标带宽、IOPS、延迟使得结果易于被其他程序解析和记录。你可以根据需求扩展这个脚本增加更多测试模式如混合读写比例rwmixread、不同块大小测试甚至生成图表。模拟真实应用负载最有效的测试是模拟真实应用的I/O模式。例如为MySQL设计一个测试job file[mysql_oltp] rwrandrw # 随机混合读写 rwmixread70 # 70%读30%写模拟典型OLTP负载 bs16k # InnoDB默认页大小 iodepth16 # 适中的队列深度 numjobs4 # 模拟4个并发连接 ioenginelibaio direct1 size10G # 总测试数据量 runtime300 # 运行5分钟 group_reporting1运行这个测试你得到的数据对评估数据库服务器的磁盘性能具有直接的参考价值。经过上面从工具选择、实战命令、环境准备到结果分析的完整流程拆解你应该已经掌握了在Linux下专业地测试磁盘读写速度的方法。核心要点再回顾一下用对工具fio为主、绕过缓存direct、设置合理的参数iodepth,bs,numjobs、理解结果IOPS、带宽、延迟分布并关联硬件特性。下次再遇到存储性能问题你就可以拿出这套方法像老中医一样通过几个测试“方子”快速准确地诊断出磁盘的“气血”到底足不足了。
返回列表