不加oflag=direct时,dd测的是内存拷贝+文件系统缓存写入速度,数据未真正落盘,测得的2GB/s实为page cache吞吐,非磁盘真实写速;靠谱命令为:time dd if=/dev/zero of=/mnt/data/testfile bs=1M count=2048 oflag=direct。

为什么dd不加oflag=direct测的不是真实写速
不加 oflag=direct 时,dd if=/dev/zero of=testfile 实际测的是内存拷贝 + 文件系统缓存写入速度,数据根本没落盘。你看到的 2GB/s 可能只是 page cache 的吞吐,硬盘本身可能只有 300MB/s。内核返回“完成”时,数据还卡在内存里,dd 就结束了。
怎么写一条靠谱的写速测试命令
这条命令兼顾真实性、可复现性和通用性:
time dd if=/dev/zero of=/mnt/data/testfile bs=1M count=2048 oflag=direct
-
/mnt/data/必须是目标磁盘挂载点(比如对应/dev/sdb1),不能是/tmp(常为 tmpfs 内存盘) -
bs=1M是 SSD 和 HDD 都较友好的起点;太小(如 4k)会放大调度和元数据开销,太大(如 64M)可能触发某些 RAID 卡异常 -
count=2048→ 写 2GB,足够摊平预热抖动,又不至于跑太久 -
oflag=direct是硬性要求,缺它结果基本无效 - 别加
conv=notrunc或seek,那会引入 seek 时间,不再是纯顺序写
结果虚高或波动大?这些操作必须做
常见现象:同一块盘,三次测试结果分别是 1.1GB/s、0.4GB/s、1.3GB/s —— 这不是设备问题,是测试方法没控住变量。
- 写完立刻读?先执行
sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"清缓存,否则读测试会从 DRAM 缓存取数 - SSD 或 RAID 卡带写缓存?加
conv=fdatasync或oflag=sync强制刷盘,但速率会明显下降(这才是真实落盘速度) - 单次测试偶然性极强,至少跑 3 次,取中间值,别信第一次
- 测试期间关掉日志轮转、备份任务、监控采集等后台 IO 干扰
测完发现和 hdparm -t 差很多,正常吗
完全正常。hdparm -t /dev/sdb 测的是裸设备物理读带宽(绕过文件系统),而 dd if=/dev/zero of=... oflag=direct 测的是「应用层→文件系统→驱动→磁盘」全链路顺序写能力。两者路径不同,数值本来就不该一致。
如果 dd 结果远高于 hdparm,大概率是没清缓存、或文件系统做了写合并/预取优化;如果低太多,要查挂载选项(如 noatime 是否启用)、条带宽度、是否启用了 journal(ext4)或 log(xfs)等开销项。
真正容易被忽略的是:dd 只反映单流大块顺序写,对数据库、虚拟机这类小 IO 随机负载毫无参考价值——那得用 fio。


















