限制Linux中缓冲区缓存的大小

限制Linux中缓冲区缓存的大小

有没有办法告诉 Linux 内核只使用一定比例的内存作为缓冲区缓存?我知道/proc/sys/vm/drop_caches可以用来暂时清除缓存,但是是否有任何永久设置可以防止缓存增长到超过主内存的 50%?

我想要这样做的原因是,我有一台运行 Ceph OSD 的服务器,它不断地从磁盘提供数据,并在几个小时内设法用完整个物理内存作为缓冲区缓存。同时,我需要运行将分配大量(数十 GB)物理内存的应用程序。与流行的看法相反(请参阅几乎所有有关缓冲区高速缓存的问题给出的建议),通过丢弃干净的高速缓存条目自动释放内存是不是瞬时:当缓冲区缓存已满 (*) 时,启动我的应用程序可能需要长达一分钟的时间,而在清除缓存(使用echo 3 > /proc/sys/vm/drop_caches)后,同一应用程序几乎立即启动。

(*) 根据 Vtune 在名为 的函数中的说法,在这一分钟的启动时间内,应用程序在新内存中出现故障,但 100% 的时间都花在内核中pageblock_pfn_to_page。这个函数似乎与查找大页面所需的内存压缩有关,这让我相信实际上碎片是问题所在。

答案1

如果您不需要绝对限制,而只是向内核施加压力以更快地刷新缓冲区,那么您应该查看vm.vfs_cache_pressure

该变量控制内核回收用于 VFS 缓存(与页面缓存和交换)缓存的内存的趋势。增加此值会增加 VFS 缓存的回收率。

范围从 0 到 200。将其移向 200 以获得更高的压力。默认设置为 100。您还可以使用该slabtop命令分析内存使用情况。就您而言,dentry*_inode_cache值必须很高。

如果你想要绝对限制,你应该查找cgroups。将 Ceph OSD 服务器放在 cgroup 中,并通过设置memory.limit_in_bytescgroup 的参数来限制它可以使用的最大内存。

memory.memsw.limit_in_bytes设置内存和交换使用量总和的最大量。如果未指定单位,则该值将解释为字节。但是,可以使用后缀来表示更大的单位 - k 或 K 表示千字节,m 或 M 表示兆字节,g 或 G 表示千兆字节。

参考:

[1]-GlusterFS Linux 内核调优

[2]-RHEL 6 资源管理指南

答案2

如果 Ceph OSD 是一个单独的进程,您可以使用cgroups控制进程使用的资源:

创建一个名为 group1 的 cgroup,并设置内存限制(例如 50GB,支持 CPU 等其他限制,示例中还提到了 CPU):

cgcreate -g memory,cpu:group1

cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1

然后,如果您的应用程序已经在运行,请将应用程序放入此 cgroup 中:

cgclassify -g memory,cpu:group1 $(pidof your_app_name)

或者在此 cgroup 中执行您的应用程序:

cgexec -g memory,cpu:group1 your_app_name

答案3

我不知道 A %,但是,您可以设置一个时间限制,以便它在 x 分钟后删除它。

首先在终端

sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

清除当前缓存。

使其成为cron-job 按 Alt-F2,输入gksudo gedit /etc/crontab, 然后在底部附近添加这一行。

 */15 *    * * *   root    sync && echo 3 > /proc/sys/vm/drop_caches

**每 15 分钟清洁一次。如果您确实想要,可以将第一个参数更改为 * 或,将其设置为 1 或 5 分钟/5 代替/15

要查看您的可用 RAM(缓存除外):

free -m | sed -n -e '3p' | grep -Po "\d+$"                          

答案4

我认为你在问题最后的预感是正确的。我怀疑 A、NUMA 感知内存分配在 CPU 之间迁移页面,或者 B,更有可能的是,透明大页面的碎片整理代码试图找到连续的、对齐的区域。

大页和透明大页已被认为可以显着提高某些工作负载的性能,但会消耗大量 CPU 时间,但不会带来太多好处。

了解您正在运行的内核、/proc/meminfo 的内容(或至少是 HugePages_* 值)以及(如果可能的话)更多引用 pageblock_pfn_to_page() 的 vtune 分析器调用图会有所帮助。

另外,如果您愿意接受我的猜测,请尝试禁用大页面碎片整理:

echo '从不' >/sys/kernel/mm/transparent_hugepage/defrag

(可能是这个,具体取决于你的内核:)

echo '从不' > /sys/kernel/mm/redhat_transparent_hugepage/defrag

最后,这个应用程序使用了几十G的内存,是你写的吗?什么语言?

既然您使用了“内存页面故障”这个术语,我猜您对操作设计和虚拟内存已经足够熟悉了。我很难想象一种情况/应用程序会出现如此严重的故障,以至于没有读取大量 I/O - 几乎总是从您试图限制的缓冲区缓存中读取。

(如果您好奇,请查看 mmap(2) 标志,例如 MAP_ANONYMOUS 和 MAP_POPULATE 以及 mincore(2),它们可用于查看哪些虚拟页实际上具有映射的物理页。)

祝你好运!

相关内容