У меня запущен микросервер 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.
Самое простое решение - это периодическая промывка буфера и кэш-памяти. Вы можете сделать это легко, запустив аналогичную 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