如何防止 ntfs-3g 使用导致我的 ZFS ARC 内存不足?

如何防止 ntfs-3g 使用导致我的 ZFS ARC 内存不足?

我有一台正在运行的 HP Microserver开放媒体库2.1.18(Stone burner),基于 Debian GNU/Linux 7(wheezy)。

几天前,我需要从 NTFS 格式的 USB 驱动器复制大量文件。我将其连接、安装并开始复制,然后让它完成。

一天后,我发现它几乎什么都没复制,我的 NAS 性能也一落千丈。调查后,我发现页面和缓冲区缓存现在占用了超过 3/4 的系统内存(它们加起来通常占用不到 10%),而 ZFS ARC 现在挤进了剩余的内存(不到正常大小的 1/4)。

当我意识到问题所在时,我停止了复制,卸载并拔下了驱动器,缓存很快又恢复到了正常大小,然后 ARC 开始自行填充到正常水平。

因此,如果我将来需要进行更多直接复制,如何防止挂载 ntfs 驱动器导致大量内存被消耗,从而使我的 ZFS ARC 缺乏所需的内存?


注意:我尝试运行echo 3 > /proc/sys/vm/drop_caches(按照 的说明“释放页面缓存、目录项和 inode” man 5 proc),因为初段绍克 建议,但这也刷新了我的 ARC(除了缓存 L2ARC 标头所需的内存)。因此,我的系统有大量可用内存,但由于内容仅缓存在 ARC 或 L2ARC 中,因此我的系统花了很长时间来重新填充 ARC,这不是理想的情况。


在这张图片中,您可以看到 5 号开始时 ZFS 饥饿情况,当时我开始进行 ntfs 复制,6 号早些时候卸载 ntfs 驱动器时一切恢复正常,最后在 7 日下午使用 drop_caches 后 ARC 被清除(并重建)。

ARC 饥饿

答案1

最简单的解决方案是定期刷新缓冲区和页面缓存内存。您可以在后台(或另一个 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,以便可以复制整个目录三。

其他选项包括:

  • 使用ddrescue而不是dd
  • cp首次加载时使用简单的libdirectio(参见这里更多细节)

最后,您可以尝试运行 NTFS 应用程序/通过复制systemd-run并设置特定的内存限制,这也适用于限制页面缓存。

相关内容