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

Это буферная среда клиента NFS Linux?

При монтировании NFS (стандартные опции RedHat 5.6 с древним ядром 2.6.18) мне кажется, что большие и множественные операции записи задерживают меньшие операции чтения. Например, выполняя простой ls в каталоге займет секунды (или минуты), если есть cp или dd работает одновременно. Проблема немного смягчена, потому что Linux кэширует метаданные на несколько секунд, но когда есть много данных для записи, монтирование NFS становится непригодным для использования.

Сначала я подумал, что это была проблема только с сервером NFS, но работала примерно так:

for((i=0; i<60; i++)) do
  strace -f -t -o strace.$i.log time stat /mnt/nfs/data > out.$i.log 2>&1
  sleep 1
  if ((i == 30)); then
    dd if=/dev/zero of=/mnt/nfs/data bs=1M count=1000 &
  fi
done

wait

а параллельный tcpdump сообщает мне следующее:

1) всякий раз, когда dd начинается, следующий stat промах в кеше занимает 15 секунд

23261 16:41:24 munmap(0x2ad024d0e000, 4096) = 0
23261 16:41:24 lstat("/mnt/fermat_emctest/data", {st_mode=S_IFREG|0600, st_size=1048576000, ...}) = 0
23261 16:41:40 open("/proc/filesystems", O_RDONLY) = 3

2) tcpdump показывает, что пока dd работает и WRITE звонки не выдаются, ни одного GETATTR отправлено. Учитывая, что RPC является асинхронным, я ожидал увидеть GETATTR звонки мультиплексируются с WRITE, но это не так. Это не GETATTR это медленно (при отправке требуется несколько нас), это ядро ​​ставит его в очередь после всех WRITEс.

Вот почему stat занимает много времени, потому что он ждет, пока ядро ​​отправит GETATTR вызов.

Я прав ? Это похоже на буфер проблема, ядро ​​голодает мой stat потому что очередь операций на стороне клиента для этого монтирования (сервера?) заполнена.

Я думаю, это как-то связано с моим другим вопросом Как добиться нескольких подключений NFS / TCP к одному серверу? .

Есть ли способ настроить очередь операций ядра NFS?

Хорошо, вот мой ответ.

Относится к https://bugzilla.redhat.com/show_bug.cgi?id=688232 с ядром 2.6.18 и 2.6.32, поставляемым с RedHat (у меня нет времени повторно проверить это с новыми ядрами vanilla), на клиенте NFS (параметры монтирования v3 / tcp / по умолчанию), когда вы пишете в файл, ядру также необходимо обновить временные метки этого файла. Если во время записи файла другому процессу нужны метаданные этого файла (например, при выполнении stat в этом файле или ls -l в его родительском каталоге), этот процесс чтения задерживается ядром до завершения записи.

На уровне NFS я вижу, что ядро ​​выдаст GETATTR звонить только в конце концов (я не уверен в этом, но в моих тестах до 5GiB stat время, казалось, соответствовало dd время) WRITE. Чем больше запись, тем дольше ожидание.

На медленном сервере NFS или сервере с большим объемом оперативной памяти эта задержка может составлять минуты. Когда stat(2) засыпает, можно следить /proc/meminfo для NFS_Unstable или Writeback который показывает, сколько данных летит.

Я не уверен, почему ядро ​​это делает, но, по крайней мере, теперь я понимаю поведение. Таким образом, буферной области нет, но некоторые операции сериализованы.