我的问题如下:
PHP的file_put_contents()
函数是否与NFS同步,如果是,是否在任何情况下?例如,如果我通过NFS交互的远程文件系统可以是EXT3或NFS,那么这是确保file_put_contents()
同步的重要因素吗?
谢谢!
答案 0 :(得分:6)
PHP甚至不知道它正在写入NFS。它使用操作系统syscalls进行文件系统访问。操作系统负责将文件系统调用抽象到用户空间应用程序,这包括远程文件系统,如NFS。
PHP中的写操作是同步的。 PHP等待系统调用完成处理其结果。但是,NFS, like other file systems, can be mounted asynchroneously,以便FS子系统可以报告成功写入,而实际上它只缓存了数据以供稍后写入。这是一个巨大的性能提升,但在服务器崩溃时可能会导致数据丢失。
但是,NFS sync
/ async
有点不同。
引用man 5 nfs
的相关部分,
NFS客户端以不同于某些其他文件系统的方式处理同步安装选项[...]。如果既未指定同步也未指定async(或者如果指定了async选项),则NFS客户端会延迟向服务器发送应用程序写入,直到发生以下任何事件:
换句话说,在正常情况下,数据写的是 应用程序可能不会立即出现在托管的服务器上 文件。
- 内存压力强制回收系统内存资源。
- 应用程序使用sync(2),msync(2)或fsync(3)显式刷新文件数据。
- 应用程序以close(2)关闭文件。
- 通过fcntl(2)锁定/解锁文件。
如果在挂载点上指定了 sync 选项,则任何系统调用该选项 将数据写入该挂载点上的文件会导致该数据 在系统调用将控制权返回给用户之前刷新到服务器 空间。这提供了客户端之间更高的数据缓存一致性,但是 以显着的性能成本。
如果在挂载点上指定了 sync 选项,则任何系统调用该选项 将数据写入该挂载点上的文件会导致该数据 在系统调用将控制权返回给用户之前刷新到服务器 空间。这提供了客户端之间更高的数据缓存一致性,但是 以显着的性能成本。
将此问题应用于您的问题,这意味着:如果您的NFS使用sync
挂载,则每个数据块都会立即写入远程系统。使用async
,文件将在file_put_contents
完成后写入远程系统。
由于file_put_contents
以原子方式工作并以fclose
结束,因此如果挂载sync
或async
- {{1}时,对您来说并不重要完成后,数据已写入远程文件系统。如果远程服务器崩溃,PHP无论如何都会抛出错误。在这种情况下,file_put_contents
没有优势。
特别是如果您正在使用大文件,sync
会非常有害,因为每个数据块都会造成用户空间→内核→网络→远程内核→远程的巨大开销文件系统通信。
因此,您应该使用sync
选项挂载NFS,这是默认选项。
顺便说一下,NFS客户端不知道远程分区是Ext3还是其他什么。它只是NFS,因此可以像任何符合POSIX的文件系统一样对待。