Мой вопрос заключается в следующем:
Это PHP file_put_contents()
функция синхронна с NFS и если да, то при каких обстоятельствах? Например, если удаленная файловая система, с которой я взаимодействую через NFS, может быть EXT3 или NFS, это важный фактор, чтобы file_put_contents()
синхронно?
Спасибо!
PHP даже не знал бы, что пишет в NFS. Он использует операционную систему Системные вызовы для доступа к файловой системе. Обязанность ОС — абстрагировать обращения файловой системы к приложениям пользовательского пространства, включая удаленные файловые системы, такие как NFS.
Операции записи в PHP являются синхронными. PHP ожидает завершения системного вызова для обработки своего результата. Тем не мение, NFS, как и другие файловые системы, может монтироваться асинхронно, так что подсистема FS может сообщить об успешной записи, когда на самом деле она только кэшировала данные для последующей записи. Это огромный выигрыш в производительности, но может привести к потере данных при сбое сервера.
Тем не менее, NFS sync
/async
немного отличается
Цитируя соответствующий раздел man 5 nfs
,
Клиент NFS рассматривает параметр монтирования синхронизации иначе, чем некоторые другие файловые системы […]. Если ни синхронизация, ни асинхронность не указаны (или если задана опция асинхронизации), клиент NFS задерживает отправку записей приложения на сервер до тех пор, пока не произойдет любое из следующих событий:
- Давление памяти вынуждает восстановление системных ресурсов памяти.
- Приложение явно сбрасывает данные файла с помощью sync (2), msync (2) или fsync (3).
- Приложение закрывает файл с помощью close (2).
- Файл заблокирован / разблокирован через fcntl (2).
Другими словами, при нормальных обстоятельствах данные, записанные
приложение может не сразу появиться на сервере, на котором размещены
файл.Если синхронизировать опция указана в точке монтирования, любой системный вызов
запись данных в файлы в этой точке монтирования приводит к тому, что данные
сбрасывается на сервер до того, как системный вызов возвращает управление пользователю
пространство. Это обеспечивает большую согласованность кэша данных среди клиентов, но
при значительных эксплуатационных расходах.Если синхронизировать опция указана в точке монтирования, любой системный вызов
запись данных в файлы в этой точке монтирования приводит к тому, что данные
сбрасывается на сервер до того, как системный вызов возвращает управление пользователю
пространство. Это обеспечивает большую согласованность кэша данных среди клиентов, но
при значительных эксплуатационных расходах.
Применяя это к вашему вопросу, это означает: если ваша NFS смонтирована с sync
каждый фрагмент данных записывается в удаленную систему мгновенно. С async
файл записывается в удаленную систему, когда file_put_contents
закончил
Как file_put_contents
работает атомарно и заканчивается fclose
в любом случае, для вас не имеет значения, смонтирован ли NFS sync
или же async
— когда file_put_contents
По окончании данные были записаны в удаленную файловую систему. В случае сбоя удаленного сервера PHP все равно выдаст ошибку. Там нет никакого преимущества с sync
в этом сценарии.
И особенно если вы работаете с большими файлами, sync
было бы очень обидно, потому что каждый кусок данных будет создавать огромные накладные расходы пользовательское пространство → ядро → сеть → удаленное ядро → удаленная файловая система коммуникации.
Поэтому вы должны смонтировать NFS с async
вариант, который по умолчанию в любом случае.
Кстати, клиент NFS не знает, является ли удаленный раздел Ext3 или каким-либо другим. Это просто NFS, и поэтому его можно рассматривать как любую POSIX-совместимую файловую систему.
Других решений пока нет …