我有一个基于 Debian GNU/Linux 7 (wheezy)运行OpenMediaVault 2.1.18 (Stone burner) 的 HP Microserver。
几天前,我需要从 USB 驱动器中复制大量文件,使用 NTFS 格式化。我连接它,安装它并开始复制并让它完成。
一天后,我发现它几乎没有复制任何东西,而且我的 NAS 性能下降了。经过调查,我发现页面和缓冲区缓存现在占用了超过 3/4 的系统内存(这些通常占用不到 10%),并且 ZFS ARC 现在被挤压到剩余内存中(小于正常大小的 1/4 )。
当我意识到出了什么问题时,我停止了复制,卸载并拔掉了驱动器,缓存很快恢复到正常大小,然后 ARC 开始自行填充到正常水平。
所以,如果我以后需要做更多的直接拷贝,我该如何防止挂载 ntfs 驱动器导致大量内存被消耗,让我的 ZFS ARC 缺乏它需要的内存?
注意:我尝试运行(按照shodanshok 的建议echo 3 > /proc/sys/vm/drop_caches
“释放 pagecache、dentries 和 inode” man 5 proc
),但这也刷新了我的 ARC(缓存 L2ARC 标头所需的内存除外)。因此,我的系统有大量可用内存,但由于仅缓存在 ARC 或 L2ARC 中,因此我的系统花费了很长时间来调整驱动器以重新填充 ARC,这不是理想的情况。
在这张图片中,您可以看到在 5 日开始时 ZFS 饥饿,当我开始我的 ntfs 副本时,在 6 日早些时候卸载 ntfs 驱动器时一切恢复正常,然后最后 ARC 被清除(并重建) 7日下午使用drop_caches。
最简单的解决方案是定期刷新缓冲区和页面缓存内存。您可以轻松地在后台(或另一个 tty)运行类似的 bash 行:
while true; do echo 1 > /proc/sys/vm/drop_caches; sleep 5; done
或者,您可以尝试不同的方法来避免污染缓冲区/页面缓存。基本上,您需要使用 DIRECT_IO 复制每个文件,完全绕过页面缓存。您可以使用类似于以下的命令来执行此操作:
dd if=srcfile of=dstfile bs=1M iflag=direct
上述命令的作用是使用 O_DIRECT 选项打开 srcfile,在读取期间绕过页面缓存,但在写入期间不绕过。如果您甚至需要绕过写入缓存,则可以附加一个
oflag=direct
选项。上述解决方案的真正问题是,必须一个一个地指定一个文件,执行多个(可能是数千个)。这意味着您必须编写脚本
dd
,以便您可以复制整个目录 3.其他选项包括:
ddrescue
而不是dd
cp
首次加载时使用简单的(有关详细信息,libdirectio
请参见此处)最后,您可以尝试运行您的 NTFS 应用程序/复制
systemd-run
并设置特定的内存约束,这也适用于限制页面缓存。