正确的使用 dd 进行磁盘读写速度测试

测试方式:使用 dd 指令,对磁盘进行连续写入,不使用内存缓冲区,每次写入 8k 的数据,总共写入 20 万次,产生 1.6G 大小的文件。

测试指令:dd if=/dev/zero of=/data01/test.dbf bs=8k count=200000 conv=fdatasync


正确的使用 dd 进行磁盘读写速度测试
dd 是Linux/UNIX 下的一个非常有用的命令,作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换,所以可以用来测试硬盘的顺序读写能力。可以写文件,可以写裸设备。

dd 语法

功能说明:读取,转换并输出数据。
语  法:dd [bs=< 字节数 >][cbs=< 字节数 >][conv=< 关键字 >][count=< 区块数 >][ibs=< 字节数 >][if=< 文件 >][obs=< 字节数 >][of=< 文件 >][seek=< 区块数 >][skip=< 区块数 >][–help][--version]
补充说明:dd 可从标准输入或文件读取数据,依指定的格式来转换数据,再输出到文件,设备或标准输出。
参  数:
bs=< 字节数 >   将 ibs(输入) 与 obs(输出) 设成指定的字节数。
cbs=< 字节数 >   转换时,每次只转换指定的字节数。
conv=< 关键字 >   指定文件转换的方式。
count=< 区块数 >   仅读取指定的区块数。
ibs=< 字节数 >   每次读取的字节数。
if=< 文件 >   从文件读取。
obs=< 字节数 >   每次输出的字节数。
of=< 文件 >   输出到文件。
seek=< 区块数 >   一开始输出时,跳过指定的区块数。
skip=< 区块数 >   一开始读取时,跳过指定的区块数。
–help   帮助。
–version   显示版本信息。

dd 常用参数详解

if=xxx  从 xxx 读取,如 if=/dev/zero, 该设备无穷尽地提供 0,(不产生读磁盘 IO)
of=xxx  向 xxx 写出,可以写文件,可以写裸设备。如 of=/dev/null,“黑洞”,它等价于一个只写文件. 所有写入它的内容都会永远丢失. (不产生写磁盘 IO)
bs=8k  每次读或写的大小,即一个块的大小。
count=xxx  读写块的总数量。

避免操作系统“写缓存”干扰测试成绩,使用 sync、fsync、fdatasync

关于 sync、fsync、fdatasync 请参考:http://elf8848.iteye.com/blog/2088986

dd bs=8k count=4k if=/dev/zero of=test.log conv=fsync
dd bs=8k count=4k if=/dev/zero of=test.log conv=fdatasync
dd bs=8k count=4k if=/dev/zero of=test.log oflag=dsync
dd bs=8k count=4k if=/dev/zero of=test.log  默认“写缓存”启作用
dd bs=8k count=4k if=/dev/zero of=test.log conv=sync   “写缓存”启作用
dd bs=8k count=4k if=/dev/zero of=test.log; sync   “写缓存”启作用

dd bs=8k count=4k if=/dev/zero of=test.log conv=fsync
加入这个参数后,dd 命令执行到最后会真正执行一次“同步 (sync)”操作,,这样算出来的时间才是比较符合实际使用结果的。conv=fsync 表示把文件的“数据”和“metadata”都写入磁盘(metadata 包括 size、访问时间 st_atime & st_mtime 等等),因为文件的数据和 metadata 通常存在硬盘的不同地方,因此 fsync 至少需要两次 IO 写操作,fsync 与 fdatasync 相差不大。(重要,最有参考价值)

dd bs=8k count=4k if=/dev/zero of=test.log conv=fdatasync
加入这个参数后,dd 命令执行到最后会真正执行一次“同步 (sync)”操作,,这样算出来的时间才是比较符合实际使用结果的。conv=fdatasync 表示只把文件的“数据”写入磁盘,fsync 与 fdatasync 相差不大。(重要,最有参考价值)

dd bs=8k count=4k if=/dev/zero of=test.log oflag=dsync
加入这个参数后,每次读取 8k 后就要先把这 8k 写入磁盘,然后再读取下面一个 8k,一共重复 4K 次。这是最慢的一种方式了。

dd bs=8k count=4k if=/dev/zero of=test
没加关于操作系统“写缓存”的参数,默认“写缓存”启作用。dd 先把数据写的操作系统“写缓存”,就完成了写操作。通常称为 update 的系统守护进程会周期性地(一般每隔 30 秒)调用 sync 函数,把“写缓存”中的数据刷入磁盘。因为“写缓存”起作用,你会测试出一个超级快的性能。
如:163840000 bytes (164 MB) copied, 0.742906 seconds, 221 MB/s

dd bs=8k count=4k if=/dev/zero of=test conv=sync
conv=sync 参数明确“写缓存”启作用,默认值就是 conv=sync

dd bs=8k count=4k if=/dev/zero of=test; sync
与第 1 个完全一样,分号隔开的只是先后两个独立的命令。当 sync 命令准备开始往磁盘上真正写入数据的时候,前面 dd 命令已经把错误的“写入速度”值显示在屏幕上了。所以你还是得不到真正的写入速度。

裸设备测试

1、裸设备到文件系统
dd if=/dev/rsd1b of=/backup/df1.dbf bs=8k skip=8 count=3841
2、文件系统到裸设备
dd if=/backup/df1.dbf of=/dev/rsd2b bs=8k seek=8