dd 测试sync、fsync和fdatasync参数详解


现在在做ceph性能方面的测试,使用dd命令测试集群的吞吐量,为了排除内存缓冲对实验结果的影响,选择创建二倍于内存的文件,命令如下:


dd if=/dev/zero of=/home/cloud/test/test.iso bs=1M count=409600 2>>/home/cloud/test/dd-16_rs.txt 


现在问题来了,我们服务器的内存是196G!创建测试文件的大小是400G,若创建文件的速度是30M/S,一个测试用例将会用将近4个小时,崩溃了~因此,详细的看了一下dd命令相关参数,重点在创建文件时,绕过内存,直接写入磁盘得到真实的ceph集群吞吐。man 了一下dd命令,看不懂。然后google了一下,在这两个连接中,在DD创建文件时都推荐使用conv=fdatasync 这个参数,又查了一下,一篇UC对ceph集群做的测试:http://tech.uc.cn/?p=1223,他们没有使用 conv=fdatasync这个参数,而使用了另


一个参数:oflag=dsync。到底使用哪个呢?在本机测试了一下,如下:


dd if=/dev/zero of=test-geml-01.iso bs=1M count=5120 conv=fdatasync   84.9 MB/秒

dd if=/dev/zero of=test-geml-02.iso bs=1M count=5120 oflag=dsync      15.1 MB/秒


因为本机拷贝速度应该大于 15.1 MB/秒,感觉还是conv=fdatasync这个参数靠谱一些


在大多数的unix/linux对磁盘io的写操作都是通过缓存来完成的,基本的原理如下:当将数据写入文件时,内核通常先将该

数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列,而是等待其写满或者当内核需要重用

该缓冲区以便存放其他磁盘块数据时,再将该缓冲排入输出队列,然后待其到达队首时,才进行实际的I/O操作。 我们称之

为延迟写,极大的减少了写磁盘的次数。


但是在没写特殊的应用中我们需要实时的将应用层数据写入到磁盘上 特别是一些高可靠性要求的系统中 数据需要及时的写入磁盘 即便是瞬时系统故障 数据也可以安全恢复,于是就有了sync、fsync和fdatasync函数。但在功能上 这三个函数又略

有区别:



     sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,它并不等待实际写磁盘操作结束。通常称为update的

系统守护进程会周期性地(一般每隔30秒)调用sync函数。这就保证了定期冲洗内核的块缓冲区。



    fsync函数只对由文件描述符filedes指定的单一文件起作用,并且等待写磁盘操作结束,然后返回。fsync可用于数据库这

样的应用程序,这种应用程序需要确保将修改过的块立即写到磁盘上。



    fdatasync函数类似于fsync,但它只影响文件的数据部分。而除数据外,fsync还会同步更新文件的属性。


【作者】张昺华


【微信公众号】 张昺华