My question is the following:
Is PHP's file_put_contents()
function synchronous with NFS and if yes, is it in any circumstances? For instance, if the remote file system I interact with through NFS can be either EXT3 or NFS, is that an important factor to make sure file_put_contents()
is synchronous?
Thanks!
PHP wouldn't even know that it's writing to NFS. It uses the operating system's syscalls for file system access. It's the OS'es duty to abstract file system calls to user space applications, this includes remote file systems such as NFS.
Write operations in PHP are synchroneous. PHP waits for the syscall to finish to process its result. However, NFS, like other file systems, can be mounted asynchroneously, so that the FS subsystem may report a successful write when in fact it has only cached the data for a later write. This is a huge performance gain, but can cause loss of data when the server crashes.
However, NFS sync
/async
is a bit different.
Quoting the relevant section of 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.
Applying this to your question, this means: If your NFS is mounted with sync
, each chunk of data is written to the remote system instantly. With async
, the file is written to the remote system when file_put_contents
has finished.
As file_put_contents
works atomically and finishes with fclose
anyway, it doesn't matter for you if NFS is mounted sync
or async
– when file_put_contents
finishes, the data has been written to the remote file system. Should the remote server crash, PHP will throw an error anyway. There's no advantage with sync
in this scenario.
And especially if you're working with big files, sync
would be very hurtful, because each chunk of data will create a huge overhead of userspace → kernel → network → remote kernel → remote filesystem communication.
Therefore you should mount NFS with the async
option, which is the default anyway.
By the way, the NFS client doesn't know if the remote partition is Ext3 or whatever. It's just NFS, and can as such be treated just like any POSIX-compliant file system.