Назад | Перейти на главную страницу

Почему при записи файла в общий ресурс NFS на сервер NFS отправляется операция COMMIT?

У меня есть сжатие 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 файла в секунду или около того. Я могу значительно увеличить скорость, если добавлю async к /etc/exports. (Запись одного большого файла в каталог, смонтированный по NFS, идет со скоростью более 100 МБ / с.)

Я просматриваю статистику сервера и вижу, что всякий раз, когда файл записывается, он «фиксируется» (это также происходит с 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" запускается fsync; если echo записал в локальный файл, а затем машина вышла из строя, файл мог быть потерян. Напротив, клиент NFS, похоже, отправляет COMMIT после завершения echo. Зачем?

Я не хочу использовать async Вариант сервера NFS, потому что он явно проигнорирует COMMIT. Мне кажется, что у меня была локальная файловая система, и мне приходилось выбирать между синхронизацией каждого файла при закрытии и игнорированием fsync все вместе. Что я неправильно понял?

потому что именно так работает NFS, и именно так она должна работать, поскольку это синхронный протокол. Что вам нужно убедиться, так это то, что экспортируемая файловая система поддерживается LUN, которые имеют защиту NVRAM / BBWC и правильно обрабатывают fsync () - т.е. игнорируют это и маскируют флаги SCSI FUA и команды SCSI_CACHE_SYNCHRONIZE. Также убедитесь, что в файловой системе не включены барьеры, если она поддерживается BBWC / NVRAM.

Таким образом, NFS сохраняет свою синхронную семантику и эквивалентна запуску fsync () после каждой записи, но вы получаете производительность асинхронной работы.