У меня запущен микросервер HP OpenMediaVault 2.1.18 (Stone Burner) на базе Debian GNU / Linux 7 (wheezy).
Несколько дней назад мне нужно было скопировать большое количество файлов с USB-накопителя, отформатированных в NTFS. Подключил, смонтировал, запустил копию и оставил до завершения.
Через день я обнаружил, что он почти ничего не скопировал, и производительность моего NAS упала. В ходе расследования я обнаружил, что страничный и буферный кеш теперь занимают более 3/4 системной памяти (вместе они обычно занимают менее 10%), а ZFS ARC теперь сжат в оставшуюся память (менее 1/4 от нормального размера. ).
Когда я понял, что не так, я остановил копию, размонтировал и отключил диск, и очень быстро кеши вернулись к своему нормальному размеру, а затем ARC начал заполняться до нормального уровня.
Итак, если мне нужно будет делать больше прямых копий в будущем, как мне предотвратить монтирование дисков ntfs, приводящее к потреблению большого количества памяти и лишению моего ZFS ARC необходимой памяти?
Примечание: я пробовал запустить echo 3 > /proc/sys/vm/drop_caches
(на «свободный кеш страниц, dentries и inodes» в соответствии с man 5 proc
), так как шоданшок предложил, но это также очистило мой ARC (за исключением памяти, необходимой для кеширования заголовка L2ARC). Таким образом, в моей системе было много свободной памяти, но поскольку все кэшируется только в ARC или L2ARC, моя система потратила целую вечность на перезарядку дисков для повторного заполнения ARC, что было нежелательным положением дел.
На этом изображении вы можете увидеть голодание ZFS в начале 5-го числа, когда я запустил свою копию ntfs, все возвращается в нормальное состояние при отключении диска ntfs в начале 6-го числа, а затем, наконец, очищается (и восстанавливается) ARC после используя drop_caches, 7-го числа днем.
Самое простое решение - периодически очищать буфер и кэш-память страниц. Вы можете легко сделать это, запустив аналогичную строку bash в фоновом режиме (или на другом tty):
while true; do echo 1 > /proc/sys/vm/drop_caches; sleep 5; done
Кроме того, вы можете попробовать другой способ избежать загрязнения буфера / кэша страниц. По сути, вам нужно скопировать каждый файл с помощью DIRECT_IO, полностью минуя кеш страницы. Вы можете сделать это с помощью команды, подобной:
dd if=srcfile of=dstfile bs=1M iflag=direct
Приведенная выше команда открывает srcfile с опцией O_DIRECT, минуя кеш страницы во время чтения. но не во время записи. Если вам нужно обойти даже кеширование записи, вы можете добавить еще один oflag=direct
вариант.
Настоящая проблема с вышеуказанным решением заключается в том, что вы должны указывать файл один за другим, выполняя несколько (возможно, тысячи). Это означает, что вам пришлось написать сценарий вокруг dd
, так что вы можете скопировать весь каталог три.
Другие варианты включают:
ddrescue
вместо того dd
cp
при первой загрузке libdirectio
(видеть Вот Больше подробностей)Наконец, вы можете попробовать запустить приложение / копию NTFS через systemd-run
и установка определенных ограничений памяти, которые также должны работать для ограничения кеширования страниц.