如何关闭单个进程的块缓存?

如何关闭单个进程的块缓存?

我有一个包含许多磁盘绑定服务的大型系统。使用块缓存它们可以更好地工作。

除此之外,还有一些备份进程正在运行。

我知道他们应该如何使用块缓存:他们绝对不应该。

备份是通过将一个块设备复制到另一个块设备来进行的buffer命令。需要任何缓存的可能性几乎为零。

但是,如果备份运行,就会使普通服务变得更糟。给予低ionice对它没有太大帮助 - 问题不在于它的 IO 优先级,而在于它用不需要的数据覆盖了块缓存。

我可以以某种方式设置此buffer命令以完全不使用块缓存吗?

如果重要的话,它会将 lvm 卷复制到另一个卷。

答案1

我找到了nocache任务的工具。

一般来说,这在 Linux 中是不可能的:没有这样的选项,或者标志,或者任何东西,可以为 a 设置什么过程

但是,那posix_fadvise(...)当需要连续读/写操作时,调用可用于通知块/缓冲区缓存子系统。 APOSIX_FADV_DONTNEED向内核提供“额外信息”,它不应该缓存它们,因为它不会在不久的将来被重新读取。

nocacheposix_fadvise(...)通过环境变量注入的共享库拦截所有重要的文件操作LD_PRELOAD

正如其名称所示,这只是一个建议;然而我的实验表明巨大的性能改进(实际上,其他重要任务可以与后台备份并行运行,而最终用户不会出现明显的性能下降)。

答案2

像这样的工具nocache实际上是不是适当的解决方案。引用无缓存的来源:

这个工具是什么不是适合:

  • 控制页面缓存的使用方式
    • 为什么你认为你在 GitHub 上找到的一些随机工具可以比 Linux 内核做得更好?
  • 防御缓存抖动
    • 使用 cgroup 来限制进程拥有的内存量。请参阅下文或在互联网上搜索,这是众所周知的,工作可靠,并且不会像此工具那样引入性能损失或潜在的危险行为。

因此,使用 cgroups(更准确地说,在 2023 年,只要有可能,肯定是 cgroupsv2)来限制您的进程可以使用的缓存量(从而限制它可以驱逐的缓存量):

如何在内存有限的 cgroup 中运行进程及其子进程

例如,如果您想要运行备份,但不希望系统因页面缓存抖动而减慢速度,请执行此操作。

如果你使用systemd

如果您的发行版使用systemd,这非常简单。 Systemd 允许在“范围”(即 cgroup)中运行进程(及其子进程),并且您可以指定转换为 cgroup 限制的参数。

当我运行备份时,我会:

$ systemd-run --scope --property=MemoryLimit=500M -- backup command 

MemoryMax对于 v2)

其效果是缓存空间受到额外的最大 500MiB 的限制:

前:

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           7.5G        2.4G        1.3G        1.0G        3.7G        3.7G
Swap:          9.7G         23M        9.7G

期间(注意 buff/cache 仅增加了约 300MiB):

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           7.5G        2.5G        1.0G        1.1G        4.0G        3.6G
Swap:          9.7G         23M        9.7G

这是如何运作的?

用于systemd-cgls列出 systemd 创建的 cgroup。在我的系统上,上述命令创建一个名为run-u467.scopesystem.slice组的组;你可以像这样检查它的内存设置:

$ mount | grep cgroup | grep memory cgroup on
/sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec
latime,memory)

$ cat /sys/fs/cgroup/memory/system.slice/run-u467.scope/memory.limit_in_bytes
524288000

相关内容