file_put_contents 是否与 NFS 同步

Is file_put_contents synchronous with NFS

我的问题如下:

PHP 的 file_put_contents() 功能是否与 NFS 同步?如果是,是否在任何情况下都同步?例如,如果我通过 NFS 与之交互的远程文件系统可以是 EXT3 或 NFS,那么这是确保 file_put_contents() 同步的重要因素吗?

谢谢!

  1. PHP 甚至不知道它正在写入 NFS。它使用操作系统的 syscalls 进行文件系统访问。 OS 的职责是抽象文件系统对用户 space 应用程序的调用,这包括 NFS 等远程文件系统。

  2. PHP 中的写入操作是同步的。 PHP 等待系统调用完成以处理其结果。但是,NFS, like other file systems, can be mounted asynchroneously,这样 FS 子系统可能会报告写入成功,而实际上它只是缓存数据以供稍后写入。这是一个巨大的性能提升,但会在服务器崩溃时导致数据丢失。

但是,NFS sync/async 有点不同。

引用man 5 nfs的相关部分,

The NFS client treats the sync mount option differently than some other file systems […]. If neither sync nor async is specified (or if the async option is specified), the NFS client delays sending application writes to the server until any of these events occur:

  • Memory pressure forces reclamation of system memory resources.
  • An application flushes file data explicitly with sync(2), msync(2), or fsync(3).
  • An application closes a file with close(2).
  • The file is locked/unlocked via fcntl(2).

In other words, under normal circumstances, data written by an application may not immediately appear on the server that hosts the file.

If the sync option is specified on a mount point, any system call that writes data to files on that mount point causes that data to be flushed to the server before the system call returns control to user space. This provides greater data cache coherence among clients, but at a significant performance cost.

If the sync option is specified on a mount point, any system call that writes data to files on that mount point causes that data to be flushed to the server before the system call returns control to user space. This provides greater data cache coherence among clients, but at a significant performance cost.

将此应用于您的问题,这意味着:如果您的 NFS 使用 sync 挂载,每个数据块都会立即写入远程系统。使用 async,文件将在 file_put_contents 完成后写入远程系统。

由于 file_put_contents 以原子方式工作并以 fclose 结束,因此挂载 NFS 对您来说无关紧要 syncasync – 当 file_put_contents完成,数据已经写入远程文件系统。如果远程服务器崩溃,PHP 无论如何都会抛出一个错误。在这种情况下 sync 没有优势。

特别是如果你正在处理大文件,sync 会非常有害,因为每个数据块都会产生巨大的 userspace → kernel 开销→ 网络 → 远程内核 → 远程文件系统 通信。

因此您应该使用 async 选项挂载 NFS,这是默认设置。

顺便说一下,NFS 客户端不知道远程分区是 Ext3 还是其他分区。它只是 NFS,因此可以像任何 POSIX 兼容文件系统一样对待。