我有一个客户端节点写入一个文件到另一个节点上的硬盘(我正在写一个平行的FS实际上)。
我想了解的是:
当我write()
(或pwrite()
)时, write
调用的确切时间返回?
我看到三种可能性:
在客户端排队I / O操作后立即write
:
在这种情况下,在数据实际上离开客户机节点之前, write
可能会返回(如果您正在写入本地硬盘驱动器,则写入调用将使用延迟写入,其中数据只是排队写入,但是当您正在写入远程硬盘?)。 我写了一个testing用例,其中我写了一个大的matrix(1GByte)文件。 没有fsync
,它显示非常高的带宽值,而与fsync
,结果看起来更现实。 所以看起来可能会使用延迟写入。
在数据传输到服务器缓冲区后write
返回:
现在数据在服务器上,但驻留在主内存的缓冲区中,但尚未永久存储在硬盘上。 在这种情况下,I / O时间应该由在networking上传输数据的时间决定。
数据实际存储在硬盘上后write
返回:
我相信这肯定不会发生在默认情况下(除非你写的真正大的文件导致你的内存被填满,最终被刷新出来等)。
另外,我想确定的是:
在程序终止而没有任何数据实际离开客户端节点的情况下会发生什么情况,使得延迟,带宽和硬盘带宽等networking参数在程序的执行时间中根本不具有特征? 考虑我们不做一个fsync
或类似的东西。
编辑:我正在使用pvfs2并行文件系统
选项3当然简单,安全。 然而,一个性能足够好以至于任何人真正关心使用它的产品质量的POSIX兼容并行文件系统,通常会使用选项1结合一些或多或少涉及的机制来避免冲突,例如,当多个客户端缓存相同的文件时。
俗话说:“计算机科学中只有两件难事:缓存失效和命名事件,以及逐个错误”。
如果文件系统应该是POSIX兼容的,那么你需要去学习POSIX fs语义,并且在获得良好的性能(或者它所跳过的POSIX语义的哪些部分,NFS)的同时查看fs如何支持这些语义。 是什么让这个有趣的是POSIX fs语义回溯到20世纪70年代,尽管如何支持网络文件系统。
我并不了解pvfs2,但通常为了符合POSIX并提供良好的性能,选项1可以与某种缓存一致性协议(例如Lustre)一起使用。 对于fsync(),实际上必须将数据传输到服务器,并在fsync()返回之前将其提交到服务器上的稳定存储(磁盘或电池支持的写入缓存)。 当然,客户端对脏页面数量有一定的限制,之后会阻塞进一步的write(),直到某些文件被传输到服务器。
你可以得到你的三个选择。 这取决于您提供给open
呼叫的标志。 这取决于如何在本地安装文件系统。 这也取决于如何配置远程服务器。
以下全部来自Linux。 Solaris和其他可能有所不同。
一些重要的open
标志是O_SYNC
, O_DIRECT
, O_DSYNC
, O_RSYNC
。
NFS的一些重要的挂载标志是ac
, noac
, nocto
, lookupcache
, lookupcache
, sync
, async
。
一些用于导出NFS的重要标志是sync
, async
, no_wdelay
。 当然,NFS输出文件系统的挂载标记也很重要。 例如,如果您从Linux中导出XFS或EXT4,并由于某种原因使用了nobarrier
标志,则服务器端的电源丢失几乎肯定会导致数据丢失。