加oflag=direct是底线,否则测的是内存带宽而非磁盘真实写速;靠谱命令为time dd if=/dev/zero of=/mnt/data/testfile bs=1M count=2048 oflag=direct,需确保目标挂载点正确、清缓存、多次测试取中间值。

dd 测出来的写速虚高,不是磁盘不行,是默认没绕过缓存——加 oflag=direct 是底线,否则你测的是内存带宽,不是磁盘。
为什么不加 oflag=direct 的结果基本无效
内核收到 write() 后,把数据扔进 page cache 就返回“成功”,dd 立刻结束计时;实际数据还卡在内存里,硬盘可能一动没动。你看到的 1.8 GB/s 很可能是 DRAM 拷贝速度,而真实落盘只有 320 MB/s。
常见错误现象:
-
dd if=/dev/zero of=testfile bs=1M count=2048→ 输出 “2.1 GB/s”,但hdparm -t /dev/sdb只有 310 MB/s - 同一块 NVMe 盘,三次测试结果分别是 2.4、0.9、1.7 GB/s —— 波动主因是缓存状态未统一
靠谱的写入测试命令长什么样
这条命令能反映「应用层→文件系统→驱动→磁盘」链路的真实顺序写能力:
time dd if=/dev/zero of=/mnt/data/testfile bs=1M count=2048 oflag=direct
关键点说明:
-
/mnt/data/必须是目标磁盘挂载点(如对应/dev/nvme0n1p1),不能是/tmp(常为 tmpfs 内存盘) -
bs=1M是平衡点:太小(如 4k)放大元数据和调度开销;太大(如 64M)可能触发 RAID 卡异常或对齐问题 -
count=2048→ 写 2GB,足够摊平预热抖动,又不至于跑太久(一般 5–15 秒) - 别加
conv=notrunc或seek,那会引入寻址时间,不再是纯顺序写
结果波动大?这些操作必须做
单次测试值意义极低,真实环境里要控变量:
- 测试前关掉日志轮转、监控采集、备份任务等后台 IO 干扰
- 每次写完立即执行
sync && sudo sh -c "echo 3 > /proc/sys/vm/drop_caches",清掉页缓存、目录项和 inode 缓存 - 若 SSD 或 RAID 卡带写缓存,加
conv=fdatasync强制刷盘(速率会明显下降,但这才是真实落盘速度) - 至少跑 3 次,取中间值;别信第一次,尤其刚重启后内核缓存行为不稳定
dd 和 hdparm 结果差很多,正常吗
完全正常。hdparm -t /dev/sdb 测的是裸设备物理读带宽(绕过文件系统),而 dd if=/dev/zero of=... oflag=direct 测的是全链路顺序写能力。两者路径不同,数值本来就不该一致。
如果 dd 结果远高于 hdparm:
- 大概率是没清缓存,或者文件系统做了写合并/预取优化(如 XFS 的
allocsize) - 如果低太多,查挂载选项(如是否启用
noatime)、ext4 journal 开销、XFS log 配置、条带宽度等
真正容易被忽略的是:dd 只反映单流大块顺序写,对数据库、虚拟机这类小 IO 随机负载毫无参考价值——那得用 fio。


















