我有一个Debian挤(2.6.32-5-amd64),这是一个NFS4服务器和客户端(它通过NFS4挂载自己)。 直接导向磁盘的本地目录是/nfs4exports/mydir ,而/nfs4mounts/mydir是通过NFS使用机器的外部IP地址挂载的相同的东西。 这里是从fstab的行:
192.168.1.75:/mydir /nfs4mounts/mydir nfs4 soft 0 0
我有一个写许多小文件的应用程序。 如果我直接写入/nfs4exports/mydir ,它每秒写入数千个文件; 但如果我写入/nfs4mounts/mydir ,它每秒钟写入4个文件。 如果向/etc/exports添加async ,我可以大大提高速度。 (将一个大文件写入NFS安装目录的速度超过100 MB / s。)
我检查服务器的统计信息,我发现每当写入文件时,它都是“提交”(这也发生在NFSv3中):
root@debianvboxtest:~# mount -t nfs4 192.168.1.75:/mydir /mnt root@debianvboxtest:~# nfsstat|grep -A 2 'nfs v4 operations' Server nfs v4 operations: op0-unused op1-unused op2-future access close commit 0 0% 0 0% 0 0% 10 4% 1 0% 1 0% root@debianvboxtest:~# echo 'hello' >/mnt/test1056 root@debianvboxtest:~# nfsstat|grep -A 2 'nfs v4 operations' Server nfs v4 operations: op0-unused op1-unused op2-future access close commit 0 0% 0 0% 0 0% 11 4% 2 0% 2 0%
现在在RFC中 ,我读到:
COMMIT操作与POSIX fsync(2)系统调用的操作和语义类似,用于将文件的状态与磁盘(文件数据和元数据刷新到磁盘或稳定的存储)进行同步。 COMMIT对客户端执行相同的操作,将服务器上任何未同步的数据和元数据清除到服务器的磁盘或指定文件的稳定存储区。
我不明白为什么客户提交。 我不认为“echo”shell内置命令运行fsync ; 如果echo写入本地文件,然后机器closures,文件可能会丢失。 相比之下,NFS客户端在完成echo后似乎正在发送COMMIT。 为什么?
我不愿意使用async NFS服务器选项 ,因为它显然会忽略COMMIT。 我觉得好像我有一个本地文件系统,我不得不selectclosures同步每个文件,并忽略fsync 。 我弄错了什么?
因为这就是NFS的工作方式,而且它是一个同步协议,所以它应该如何工作。 您需要确保导出的文件系统由具有NVRAM / BBWC保护的LUN支持,并正确处理fsync() – 即忽略该文件,并屏蔽SCSI FUA标志和SCSI_CACHE_SYNCHRONIZE命令。 如果BBWC / NVRAM支持,请确保文件系统没有启用屏障。
这样,NFS保持同步语义,相当于在每次写入之后运行fsync(),但是会获得asynchronous运行的性能。