Оптимизация NFSv3

Опубликовано 1 Сентября, 2009 под тегами

В основном смысл статьи в том, чтобы оптимизировать производительность NFS. Однако, некоторые описываемые вещи не имеют к задаче прямого отношения, хотя и улучшают ощущения от работы с NFS в целом. Использованы следующие предположения: канал между клиентом и сервером не хуже 100M, не имеет заметных потерь (пинги идут яки часы), и ни клиент, ни сервер не имеют привычки ВНЕЗАПНО перезагружаться. В общем сферический клиент-сервер в ваккууме. В оптимизации помогут опции монтирования со стороны клиента.

Итак, по порядку:

  • async – вообще стоит по умолчанию, но мало ли. Улучшает отзывчиваость системы, хотя если клиент или сервер имеет привычку ВНЕЗАПНО уходить в ребут, может привести к потере данных.
  • noatime – применимо не только к НФС. Не обновляет время доступа к файлу при, собственно, доступе. Под доступом имеется ввиду даже просто ls, поэтому вещь полезная. Если, конечно, не нужно знать, когда на файл смотрели/читали последний раз. По моему опыту, это обычно не нужно.
  • udp – заставляет NFS использовать udp-транспорт. В общем случае при малых потерях пакетов udp быстрее, чем tcp за счет того, что udp не проверяет целостность цепочки пакетов. Следует заметить, однако, что при плохом соединении (с сильно плавающей скоростью или потерями) лучше использовать tcp – в таких условиях он быстрее.
  • hard,intr – это рекомендованные для всех NFS-маунтов опции, регулирующие поведение системы при потере сервера (упал/ребутнулся сервер, накрылось соединение и тп). Вообще, существует два варианта поведения. Hard подвешивает операцию ввода-вывода, пока сервер снова не появится. Soft сообщает об ошибке и дальше считает, что это не проблема подсистемы NFS. К сожаленью, как часто бывает, не все приложения корректно обрабатывают возвращаемую ошибку, что черевато потерей данных. Поэтому в общем случае рекомендуется hard. soft можно попробовать, если ФС примонтирована только для чтения. Intr нужно для того, чтобы в случае подвешивания операции ввода-вывода была возможность “убить” подвешенный процесс. Без нее процесс проявляет удивительную жизнестойкость и только жестокий kill -SIGKILL поможет окончить его муки. В присутствии soft, intr игнорируется
  • rsize=%d,wsize=%d, где %d – число – регулирует размеры сетевого буфера при чтении и записи соответсвенно. На ядрах 2.4 и выше, максимальное значение 32768 (32К). Общие рекомеднации по конкретным цифрам дать сложно, потому ограничусь утверждением, что наилучший результат на моем гигабитном канале с полным дуплексом был получен при максимальном размере буферов. Официально рекомендованно 8192, так что можно использовать это значение в качестве fail-safe default (особенно, учитывая, что это максимум для старых ядер с NFSv2).

Итак, суммируя все вышесказанное, в более-менее общем случае имеет смысл монтировать NFS-шару со следующими параметрами:

mount -t nfs -o rw,async,noatime,udp,hard,intr,rsize=8192,wsize=8192

или, если нужна отзывчивость при падении сервера, но не нужна возможность записи

mount -t nfs -o ro,async,noatime,udp,soft,rsize=8192,wsize=8192

или, если нужна надежность записи (т.е. сервер и/или клиент склонен к падениям, а канал – к обрывам)

mount -t nfs -o rw,sync,noatime,udp,hard,intr,rsize=8192,wsize=8192

Ясно, что в связи с вышесказанным, значения rsize и wsize подбираются от конкретной ситуации, и общие рекомендации по ним дать сложно.

Те же самые параметры монтирования с успехом записываются в fstab.