要测磁盘绝对写入速度,必须加oflag=direct绕过page cache,并用conv=fdatasync确保数据真正落盘;输出路径须在目标磁盘(如/mnt/data/test),避免/tmp等内存文件系统;bs=1M、count=2048写2GB,重复3次取中间值,结果远高于hdparm则说明缓存未清或文件系统干扰。

要测磁盘的绝对写入速度,核心是让数据真正落盘,而不是停留在内存缓存里。默认的 dd 命令写的是 page cache,看到的可能是 2GB/s,但硬盘实际可能只有 300MB/s——那不是磁盘速度,是内存速度。
必须加 oflag=direct 跳过缓存
这是底线要求。不加它,dd if=/dev/zero of=testfile 只是把数据拷进内核页缓存就返回了,根本没发给磁盘。
-
oflag=direct强制使用 O_DIRECT,绕过 page cache,直接与块层交互 - 输出路径必须落在目标磁盘上,比如
/mnt/data/test(对应/dev/sdb1),不能是/tmp(常为内存文件系统) - 别用
conv=notrunc或seek,它们会引入寻址开销,测的不是纯顺序写
必须加 conv=fdatasync 确保数据落盘
仅用 oflag=direct 还不够:它跳过了缓存,但 ext4/xfs 的日志、元数据可能仍滞留在驱动或磁盘 DRAM 缓存中。内核返回“完成”时,数据未必已写入 NAND 或盘片。
-
conv=fdatasync在整个写操作结束后调用fdatasync(),强制刷写数据和关联元数据到持久介质 - 效果比
oflag=dsync更实用:后者每次写一块都同步,性能极低,适合测日志类小事务,不是测吞吐 - 不要写成
dd ... ; sync——sync在dd结束后才执行,起不到作用
合理设置参数避免干扰
参数选得不合适,结果要么虚高,要么被调度抖动淹没。
-
bs=1M是较优起点:太小(如 4K)放大元数据和调度开销;太大(如 64M)可能触发 RAID 卡异常 -
count=2048→ 写 2GB:足够摊平预热波动,又不会跑太久 - 测试前关掉后台 IO 干扰:日志轮转、监控采集、备份任务
- 单次结果偶然性大,至少跑 3 次,取中间值,别信第一次
验证是否真的在测磁盘,而不是其他环节
如果结果远高于 hdparm -t /dev/sdb(裸设备读带宽),大概率是没清缓存或文件系统优化干扰;如果低太多,检查挂载选项(如是否启用 noatime)、ext4 journal 开销、XFS log 配置等。
-
dd测的是「应用→文件系统→驱动→磁盘」全链路顺序写,不是裸盘能力 - 它只反映单流大块顺序写极限,对数据库、虚拟机等随机小 IO 无参考价值——那种场景该用
fio - 真实业务性能 ≠
dd结果,但它能快速排除硬件级瓶颈











