Как предотвратить истощение памяти ZFS ARC при использовании ntfs-3g?

У меня запущен микросервер HP OpenMediaVault 2.1.18 (Stone burner), на основе Debian GNU / Linux 7.

Несколько дней назад мне нужно было скопировать большое количество файлов с USB-накопителя, отформатированного в NTFS. Я подключил его, смонтировал, запустил копирование и оставил его для завершения.

Через день я обнаружил, что он практически ничего не скопировал, и производительность моего NAS упала. Расследование, но это также очистило мой ARC (за исключением памяти, необходимой для кеширования заголовка L2ARC). Таким образом, в моей системе было много свободной памяти, но поскольку все кэшируется только в ARC или L2ARC, моя система потратила целую вечность на перезарядку дисков для повторного заполнения ARC, что не является желательным положением вещей.


На этом изображении вы можете увидеть голодание ZFS в начале 5-го числа, когда я запустил свою копию ntfs, все возвращается в нормальное состояние при отключении диска ntfs рано 6-го, а затем, наконец, очищается (и восстанавливается) ARC после использования drop_caches во второй половине дня 7.

ARC starvation

0
задан 13 April 2017 в 15:14
1 ответ

Самое простое решение - это периодическая промывка буфера и кэш-памяти. Вы можете сделать это легко, запустив аналогичную bash-строку в фоновом режиме (или в другом tty):

while true; do echo 3 > /proc/sys/vm/drop_caches; sleep 5; done

UPDATE: так как кажется, что вышеприведенное решение не работает так, как нужно, вы можете попробовать другой способ, чтобы избежать загрязнения буфера/пагечного кэша. В основном, вам нужно скопировать каждый файл, используя DIRECT_IO, полностью обходя кэш страниц. Это можно сделать командой, подобной:

dd if=srcfile of=dstfile bs=1M iflag=direct

Вышеуказанная команда открывает src-файл с опцией O_DIRECT, минуя кэш страниц во время чтения , но не во время записи . Если вам нужно обойти даже записывающее кэширование, вы можете добавить дополнительную опцию oflag=direct.

Реальная проблема с вышеописанным решением заключается в том, что вы должны указать файл один за другим, выполняя несколько (возможно тысячи). Это означает, что вы должны были написать сценарий вокруг dd, чтобы можно было скопировать целую директорию три. Другие варианты включают:

использовать ddrescue вместо dd

  • использовать простую cp при первой загрузке libdirectio (подробнее см. здесь)
  • UPDATE 2:

    Похоже, что выполнение echo 1 > /proc/sys/vm/drop_caches освобождает большую часть буферного и страничного кэшей, не освобождая при этом ARC, так что это может быть хорошим решением:

    while true; do echo 1 > /proc/sys/vm/drop_caches; sleep 5; done
    
    1
    ответ дан 4 December 2019 в 16:46

    Теги

    Похожие вопросы