dd命令

dd命令的强大,毋庸置疑,下面抛砖引玉。其中关于缓存,我理解为:从文件提取数据流,会先放到读缓存(关联ibs字节),也即读;写同理,先放到写缓存(关联obs)

dd常见的参数 如下:
if 输入文件 ,缺省为标准输入
of 输出文件,缺省为标准输出
ibs 一次性写入到输入缓存区的字节数
obs 一次性从缓存区读出的字节数
bs 等于ibs和obs
cbs(conversion buffer size) 一次性转换缓存字节数
skip 跳过输入缓存区的 多少个ibs 字节数
seek 跳过读缓存区的 多少个obs字节数
count 多少个ibs块复制到输出文件

还有conv转换参数,如下:
conv=ASCII:把EBCDIC码转换为ASCIl码。
conv=ebcdic:把ASCIl码转换为EBCDIC码。
conv=ibm:把ASCIl码转换为alternate EBCDIC码。
conv=block:把变动位转换成固定字符。
conv=ublock:把固定位转换成变动位。
conv=ucase:把字母由小写转换为大写。
conv=lcase:把字母由大写转换为小写。
conv=notrunc:不截短输出文件。
conv=swab:交换每一对输入字节。
conv=noerror:出错时不停止处理。
conv=sync:把每个输入记录的大小都调到ibs的大小(用NUL填充)。

flag参数如下:
iflag=FLAGS:指定读的方式FLAGS,参见“FLAGS参数说明”
oflag=FLAGS:指定写的方式FLAGS,参见“FLAGS参数说明”
FLAGS参数说明:
append -append mode (makes sense only for output; conv=notrunc sug-gested)
direct:读写数据采用直接IO方式;
directory:读写失败除非是directory;
dsync:读写数据采用同步IO;
sync:同上,但是针对是元数据
fullblock:堆积满block(accumulate full blocks of input )(iflag only);
nonblock:读写数据采用非阻塞IO方式
noatime:读写数据不更新访问时间

那么现在理解下真正的读操作

1)
dd命令是一个非常强大的命令,对于一些比较底层的问题,使用dd命令往往可以得到出人意料的效果。我们可以用它来测试磁盘的读写性能。之前一直以为他只能测试块设备,但是今天看到一个文章说他同时是可以测试文件系统的(IOzone也是可以测试文件系统跟块设备,但IOmeter是不能用来测试文件系统的)。

而对于dd命令,我们常用到的两个设备就是 /dev/null /dev/zero ,因为避免覆盖此文主题,所以对该特殊设备 见这里说明:http://blog.csdn.net/menogen/article/details/38060003

dd有有些参数是挺难理解的,今天用了两个小时才弄明白了conv=fsync以及oflag=sync/dsync之间的区别

我们知道 使用dd来测试硬盘读写速度只能提供一个大概的测试结果,而且是连续IO 而不是随机IO ,理论上文件规模越大,测试结果越准确。理论上bs越大,所测得性能越高
如何真正写磁盘
dd if=/dev/zero of=test bs=64k count=16k 这个是不准确的,因为命令结束的时候数据还没有真正写到磁盘上去,因为对磁盘的写,我们一般是先写到了缓存就返回了。

2)
我们来看dd的帮助页面对于一些参数的解释

the FLAG 参数(完整的看手册哦,这里假设你是知道iflag跟oflag的)
-dsync
Use synchronized I/O for data. For the output file, this forces a physical write of output data on each write. For the input file, this flag can matter when reading from a remote file that has been written to synchronously by some other process. Metadata (e.g., last-access and last-modified time) is not necessarily synchronized.
-sync likewise, but also for metadata

the CONV参数
-fsync   Synchronize output data and metadata just before finishing. This forces a physical write of output data and metadata

dsync跟sync比较好理解,前者是只同步写数据,sync同时写元数据

3)实际验证

但是感觉dsync与 -fsync怎么感觉有些一样? 网上的说法是 dd if=/dev/zero of=test bs=64k count=4k oflag=dsync 这个可以当成是模拟数据库插入操作,所以很慢,但还是没太明白。

后来自己认真的抠了这英文用词, conv=fsync Synchronize output data and metadata just before finishing 意思也就是在dd命令结束前同步data和metadata,那就是不是每一次写都同步一次咯,也就是如果我们在dd命令中写了100次,他可能是等到最后的时候才把他们同步到磁盘。而oflag=dsync是说Use synchronized I/O for data. For the output file, this forces a physical write of output data on each write,注意这里边用词 a physical write of output data on each write,那就是他是每一次写都得等到这一次写写到了磁盘才进行下一个写,也就是如果我们使用dd写100次,他每次写都是写到磁盘后才进行下一次写的。所以这样当然要比conv=fsync慢一些吧。那么自己感觉如果只是写一次的话,两者应该是差别不大的,后来做了下小实验,证实确实是这样的。

 在第一个图中,我们只写1块,然后使用oflag=sync与conv=fsync 测出来一个是32.1kb/s 一个是37.8kb/s 差别不大。但是下一个我写1000个,conv=fsync就明显的比oflag=dsync/sync快很多了,所以觉得上面自己扣的英文的理解应该是正确的。

所以在用dd做读或者写的时候,应该要注意自己的使用场景,如果需要将数据写入磁盘的话

dd if=/dev/zero of=test bs=64k count=16k 是不准确的,

而 dd if=/dev/zero of=test bs=64k count=16k conv=fsync 比较准备,他在dd结束前会写到磁盘,

而dd if=/dev/zero of=test bs=64k count=4k oflag=dsync或者sync 是真正的每写一次就写一次磁盘,所以其实可以听到磁盘啪啪啪的响的。

4)dd如何绕开cache
如果要规避掉文件系统cache,直接读写,不使用buffer cache,需做这样的设置
iflag=direct,nonblock
oflag=direct,nonblock
iflag=cio
oflag=cio
direct 模式就是把写入请求直接封装成io 指令发到磁盘
非direct 模式,就把数据写入系统缓存,然后就认为io 成功,并由操作系统决定缓存中的数据什么时候被写入磁盘

 

 其他:

常规意义上的测试磁盘写能力,注意这里没有设定以上说明的iflag oflag以及conv参数,time指令输出运行时间。

time dd if=/dev/zero of=/test.dbf bs=8k count=300000 
因为/dev/zero是一个伪设备,它只产生空字符流,对它不会产生IO,所以,IO都会集中在of文件中,of文件只用于写,所以这个命令相当于测试磁盘的写能力。
测试磁盘读能力
time dd if=/dev/sdb1 of=/dev/null bs=8k 
因为/dev/sdb1是一个物理分区,对它的读取会产生IO,/dev/null是伪设备,相当于黑洞,of到该设备不会产生IO,所以,这个命令的IO只发生在/dev/sdb1上,也相当于测试磁盘的读能力。

参考:https://blog.csdn.net/liqiangyang/article/details/80734997

原文地址:https://www.cnblogs.com/weihua2020/p/13719421.html