十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Linux磁盘性能体检:dd命令测速全攻略

Linux磁盘性能体检:dd命令测速全攻略 给服务器做性能体检或者新入手一块硬盘想先摸个底我一般不会直接上fio这种重型工具而是先甩两条dd命令。不是fio不好而是dd在几乎所有Linux发行版里都自带语法简单几十秒内就能把磁盘读写速度测出个大概数用来快速判断瓶颈到底在不在磁盘IO上非常顺手。这篇文章就是把dd测速这件事从头到尾讲透。包括常用参数怎么选、为什么写测试要加convfdatasync、为什么读测试要先清缓存、bs和count怎么搭配、测出来的数字该怎么解读以及我实际用dd过程中踩过的那些坑。适合刚接触Linux的读者也适合已经用过dd但没深究过原理的运维同行。1. dd命令到底在测什么先搞清边界再动手1.1 dd测速的口诀if、of、数据管道dd最初的设计用途是数据拷贝全称叫device to device。它的核心逻辑就一句话从if指定的输入文件读数据往of指定的输出文件写数据直到读完或写完count规定的次数。所以当你用dd测速的时候测的其实是一条完整数据管道的吞吐能力源设备或缓存 → 文件系统层 → 块设备驱动 → 物理硬件。这条管道里任何一环慢都会体现在dd的输出数字上。理解了这一点很多困惑就能解开。比如有人跑ddof指向普通文件速度出来是每秒几个GB觉得磁盘性能好得惊人——其实数据可能根本没落到磁盘上只是在内存的page cache里打了个转dd就汇报“拷贝完成”了。这种结果测的是内存速度不是磁盘速度。1.2 为什么不用fio偏偏要用dd现在性能测试工具不少fio是公认的专业选手能模拟各种IO模型hdparm也能看裸设备速度。那为什么还要用dd我的理由是快、简单、零依赖。生产服务器上排查IO瓶颈或者刚装完系统想快速验证磁盘状态dd不需要安装任何额外软件直接敲命令就能看结果。fio虽然功能强但参数复杂输出信息量大对“只想快速判断磁盘是不是太慢”的场景来说有点杀鸡用牛刀。dd的缺点也要心里有数它默认是顺序IO测不了小的随机4K读写它单线程无法模拟多队列并发它不会帮你区分IOPS和吞吐量的差异。所以我的习惯是dd负责“毛估”一旦发现异常再上fio和iostat做进一步验证。这篇文章后面会专门讲怎么交叉验证。2. 测速前的准备工作和核心参数拆解2.1 测试环境和文件大小的选择别拿到命令就开跑先想清楚三件事。第一测哪块盘。写测试会真实产生数据写入如果把of路径指到了系统盘、数据盘或者某个正在使用的挂载点轻则占满磁盘空间重则覆盖业务文件。我一般会准备一块专门用于测试的盘或者分区至少也是一个随时可以清理的目录比如/tmp如果它是独立分区的话或者新挂载的测试目录。第二当前系统负载。如果机器上正跑着数据库批量任务或者大量应用dd测出来的数字会偏低而且波动很大。我通常会在负载相对低的时间段测试或者至少记录下当时有没有其他IO任务在跑。第三测试文件大小。这个很重要后面单独讲。2.2 dd关键参数逐个说清楚dd的完整参数很多但测磁盘速度时用到的主要就下面这几个参数作用备注if输入文件路径/dev/zero最常用因为能无限提供零字节读源不会成为瓶颈of输出文件路径写测试填这里读测试填/dev/nullbs每次读写的块大小单位支持K、M、G等直接影响IO模型count读写块的数量bs乘以count等于总数据量convfdatasync写测试结束时强制同步到磁盘不加它数据可能还停在内存缓存里oflagdirect绕过page cache直接读写更接近真实硬件速度但某些文件系统不支持statusprogress显示实时进度文件大时能避免干等增强确认感2.3 bs和count怎么搭配才科学bs和count的乘积就是dd写入或读取的总数据量。比如bs1M count4096就是每次读写1MB重复4096次总共4GB。那测试文件该多大我的经验是至少要比系统可用内存的一半大。因为写测试时数据会先落到page cache里如果测试文件太小可能整个文件都留在缓存中dd还没等到真正写盘就结束了测出的速度严重虚高。假如机器内存32GB测试文件至少16GB往上写到后面才会逼着系统把数据刷盘。但也不用无限大太大了浪费时间而且可能把磁盘写满。bs的选择要看你想模拟什么场景。测顺序大文件读写比如视频文件、备份文件、日志归档bs1M或4M是常见选择如果想了解更接近数据库小IO的场景可以测bs4K或16K。注意不同bs结果差异很大这是正常的后面第五章会有对比。3. 写速度测试实操一条命令看真实写盘能力3.1 最常用的写测试命令与输出解读假设测试目录是/data/test先创建一个测试目录然后用下面这条命令测写速度mkdir -p /data/test dd if/dev/zero of/data/test/testfile bs1M count4096 convfdatasync statusprogress正常情况下输出大概长这样40960 records in 40960 records out 4294967296 bytes (4.3 GB, 4.0 GiB) copied, 8.5 s, 505 MB/s我来解释一下records in和records out分别表示读入了4096个块、写出了4096个块数量一致说明过程完整4294967296 bytes是总共拷贝的字节数正好是4GBcopied, 8.5 s表示耗时8.5秒最后的505 MB/s就是dd最终计算出的平均吞吐速度。这个505 MB/s就是写性能的初步结论。如果这是机械硬盘500MB/s左右已经接近SATA接口上限如果是普通SATA固态这个数字也算正常如果是NVMe固态这速度反而偏低了需要再排查。3.2 别被缓存骗了fdatasync和direct的真正用途写测试最常踩的坑就是“结果快得离谱”。原因就是我前面说的数据先写进了page cachedd写完后跟你汇报速度实际上磁盘可能还在后台慢慢刷。解决这个问题有两种思路。第一种加convfdatasync。它的作用是让dd在全部数据拷贝完成后调用一次fsync强制把脏数据刷到磁盘上刷盘时间也会计入总耗时。这样输出的速度基本是真实落盘速度代价是耗时会长一些。第二种用oflagdirect绕过page cache。直接以Direct IO方式写盘不经过内核缓存测出来的数字更接近“磁盘硬件能接收的速度”。数字通常比fdatasync略低但更硬核。两条命令对比一下差异很直观# 带fdatasync结果接近真实落盘 dd if/dev/zero of/data/test/testfile bs1M count4096 convfdatasync # 带direct绕过缓存结果更接近硬件能力 dd if/dev/zero of/data/test/testfile bs1M count4096 oflagdirect顺便说一句oflagdirect不是所有文件系统都支持像tmpfs这样的内存文件系统就会报错。所以我的习惯是能用direct就用direct不能用就加fdatasync。3.3 多轮测试速度波动怎么看单次测速只能当参考真正的性能判断要看多轮测试的趋势。我会连续测三次每次之间歇几秒钟记录每次的速度值然后取中位数作为参考。原因是磁盘性能受很多因素影响系统有没有后台任务、磁盘垃圾回收有没有在跑、SSD的SLC缓存有没有用完、云盘的IOPS配额是不是已经打满。三次结果如果都在一个区间内波动比如480MB/s、510MB/s、495MB/s说明磁盘状态稳定如果三次分别是800MB/s、300MB/s、500MB/s波动很大那就要怀疑系统里有其他IO负载或者磁盘本身有问题了。另外提醒一句测试完记得删掉测试文件rm -f /data/test/testfile不然一个4GB文件留在生产目录里回头清理的时候又是一顿折腾。4. 读速度测试实操清缓存后的冷读才算数4.1 先制造一个合适的读样本文件测读速度之前得先有一个足够大的读源文件。如果测系统盘可以直接读现有的大文件比如日志文件、系统镜像如果想严格控制变量就先用dd写一个测试文件出来。我一般是这么干的dd if/dev/zero of/data/test/testfile bs1M count4096 convfdatasync这个命令和写测试一模一样目的就是生成一个4GB的、内容全是零的文件。注意文件大小同样要大于内存的一半不然下面的冷读测试就不准了。4.2 冷读测速完整流程生成好测试文件后关键一步来了清空page cache。sync echo 3 /proc/sys/vm/drop_cachessync先把内存里的脏数据刷到磁盘echo 3 /proc/sys/vm/drop_caches清空page cache。这个命令需要root权限普通用户要用sudo。清缓存这一步的目的是确保下面读文件时数据不是从内存缓存里直接返回的而是实实在在地从磁盘读出来。这一步不做读测试的结果就废了。清完缓存立刻执行读测速dd if/data/test/testfile of/dev/null bs1M count4096 statusprogress输出和写测试类似也会给你一个速度值。of/dev/null就是把读出来的数据直接丢弃不产生任何写操作测的就是纯读性能。测完之后不用清缓存了但建议顺手删掉测试文件免得占用空间。4.3 热读和冷读为什么能差几十倍清缓存再读测的是冷读——数据真正来自磁盘不清缓存直接读同一个文件测的是热读——数据来自内存page cache。这两者差距极大。不信你可以试试清缓存读一次记录速度然后不清缓存马上再读一次速度几乎肯定翻几倍。因为第二次读的时候文件已经被内核缓存在内存里了磁盘根本没参与IO。所以记住一个原则读测试必须冷读才有效。如果你在生产环境测读速度跑完发现速度是好几GB每秒先别高兴想想是不是没清缓存测了个寂寞。另外drop_caches在生产环境要谨慎使用。清缓存会短暂影响正在运行的服务尤其是数据库这类依赖文件缓存的应用清完之后可能有一段性能下降。我一般只在业务低峰期做或者干脆在专门用于测试的机器上做。5. 进阶测试随机读写和块大小对性能的影响5.1 用dd简单模拟随机读很多人测完顺序读写就收工了但真实业务往往不是大文件顺序读写而是大量小块随机IO比如数据库、消息队列。dd虽然不擅长随机测试但也能勉强模拟个大概方法是利用skip参数跳过一些偏移不按顺序读。举个例子文件是4GB想把4KB作为块大小随机读一些位置dd if/data/test/testfile of/dev/null bs4K count256 skip$((RANDOM % 100000)) statusprogressskip参数表示从输入文件开头跳过多少个块再开始读结合$RANDOM随机值就能让每次读的位置不太一样。重复执行多次取平均速度能粗略感受到这块盘在小块随机读场景下的表现。但必须说明这种方式的严谨程度远不如专业工具它没法控制并发度也没法精确模拟随机分布。想认真测随机性能还是推荐fiofio --namerandread --ioenginelibaio --direct1 --runtime30 --bs4k --rwrandread --filename/data/test/fio-test --size1G5.2 不同块大小对吞吐量的影响块大小对测速结果的影响实测下来非常明显。同一块盘用bs4K和bs1M测速度可能差出好几倍。我拿手头一台普通SATA SSD测过一组数据bs写速度读速度说明4K58 MB/s112 MB/s小块IO单次读取量小通道利用率低64K305 MB/s460 MB/s块增大效率明显提升1M520 MB/s540 MB/s顺序大IO接近接口上限这组数据的规律是块越大吞吐越高但到一定量级后增速放缓。原因在于每次IO都有固定开销比如寻址、传输准备等块太小导致开销占比高接口带宽利用不起来。所以你在用dd测速的时候一定要明确自己模拟的是什么负载。测日志归并、视频存储这类大文件场景用1M没问题但如果磁盘上跑的是数据库至少加一组4K的测试做对比否则得出的结论会严重偏乐观。5.3 光靠dd不够建议配合iostat交叉验证dd测出结果后我通常会再挂一个工具去验证最常用的是iostat -x 1。在dd跑的同时另开一个终端执行iostat -x 1你会看到实时刷新的磁盘性能指标重点关注%util磁盘利用率、await平均IO响应时间、w_KB/s每秒写吞吐。如果dd显示速度很高但%util也接近100%说明磁盘已经满载了如果%util很低dd速度却不理想那瓶颈可能不在磁盘而在文件系统、CPU或者dd本身。交叉验证最大的价值是避免被dd的单一数字误导。有一次我在一台云服务器上测速dd写速度只有30MB/s但本机根本没跑什么业务。查了半天最后发现是云盘IOPS配额早就被其他实例占满了。这种情况光看dd结果会误判成磁盘故障结合iostat和云控制台的监控才能定位到真正原因。6. 常见问题与排查技巧实录6.1 我实测中遇到的5个典型问题整理一个实际工作中遇到的高频问题速查表供参考问题现象可能原因排查思路解决方式测出的写速度是每秒几GB数据停在page cache实际没落盘检查命令有没有加convfdatasync加convfdatasync或oflagdirect读速度第一次高、第二次巨高第二次命中page cache成了热读确认测前是否执行了drop_caches读测速前先sync再清缓存不同时间测同块盘速度差异大系统里有其他IO任务或SSD在垃圾回收用iostat -x 1观察磁盘利用率低负载时测或多次取中位数写测试卡了很久没结束磁盘本身慢或云盘IOPS被限制看dd有没有输出进度配合iostat确认测试文件大小耐心等待或降低bs测试文件删不掉文件被某个进程占用了用lsof查打开该文件的进程结束后台进程再删或重启后清理6.2 测速前必看的几条避坑建议第一of路径千万核对清楚。我见过不止一次有人把of后面的文件名写漏直接写成了裸设备路径导致分区数据被冲掉。建议在测试目录下建一个独立子目录每次测速都在这个子目录里操作路径清晰误操作的几率小很多。第二count别设太大了。有些机器内存很大测试文件相应也要很大但如果你是在临时目录测速要留意df -h的输出别让测试文件撑爆根分区。我通常先看下磁盘剩余空间再计算合适的count值。第三多轮测试之间最好留个几秒缓冲。写测速会触发磁盘写入队列堆积连续跑会跟前一轮的残余IO重叠导致结果偏高或偏低。第四别拿dd的结果直接对比网上看到的“标准值”。不同文件系统、不同挂载参数、不同磁盘类型、不同内核版本都会影响dd的数据。网上看到的所谓“某型号磁盘速度”参考价值很低。正确的做法是同一块盘、同一个测试方法、同一时间段内互相对比判断的是相对趋势不是绝对数值。最后分享一个小技巧上面这些章节基本覆盖了dd测速的常用场景。最后再分享一个我自己的习惯我会在跑dd前先记录一下测试盘的挂载参数比如mount | grep /data确认挂载选项里有没有影响性能的参数比如有没有开启noatime、是不是走了网络文件系统。这能帮我预判结果是否合理。比如网络文件系统NFS、CIFS的测速结果和本地盘完全没有可比性。dd测速的定位我再用一句话总结它是个趁手的快速体检工具能让你在几十秒内对磁盘能力有个大概判断但别把它当成性能验收的标准。真到了要下单采购磁盘、做存储架构选型的时候一定得上fio跑一轮完整的基准测试把IOPS、延迟、混合读写这些指标都拉出来看。工具各有分工看清楚dd能干什么、不能干什么你就能真正用好它。
返回列表