我想运行一个对它们将间接触发的内核对象进行限制的任务。注意,这不是关于应用程序使用的内存、线程等,而是关于内核使用的内存。具体来说,我想限制数量索引节点缓存任务可以使用的。
我的激励例子是updatedb
。它可以使用大量的索引节点缓存,用于以后大部分不需要的事情。具体来说,我想限制ext4_inode_cache
中的行指示的值/proc/slabinfo
。 (请注意,这不包含在 所示的“缓冲区”或“缓存”行中free
:这只是文件内容缓存,slab 内容是内核内存并记录在“已使用”列中。)
echo 2 >/proc/sys/vm/drop_caches
之后释放缓存,但这对我没有任何好处:无用的东西取代了我想保留在内存中的东西,例如正在运行的应用程序及其常用文件。
该系统是具有最新(≥ 3.8)内核的Linux。我可以使用 root 访问权限来进行设置。
如何在有限的环境(容器?)中运行命令,以便该环境对(ext4)inode 缓存的贡献仅限于我设置的值?
答案1
按照我自己的问题兰卡梅勒这可以使用以下方式存档对照组 v2:
先决条件
- 确保您的 Linux 内核已
MEMCG_KMEM
启用,例如grep CONFIG_MEMCG_KMEM "/boot/config-$(uname -r)"
- 根据操作系统(和版本),通过在 Linux 内核命令行上指定
systemd
来启用,例如通过.cgroups2
systemd.unified_cgroup_hierarchy=1
/boot/grub/grub.cfg
- 确保
cgroup2
文件系统安装在/sys/fs/cgroup/
例如mount -t cgroup2 none /sys/fs/cgroup
或等效文件系统上/etc/fstab
。 (systemd
默认情况下会自动为您执行此操作)
祈求
- 为您的进程创建一个新组
my-find
(每次启动一次):mkdir /sys/fs/cgroup/my-find
- 将(当前)进程(及其所有未来的子进程)附加到该组:
echo $$ >/sys/fs/cgroup/my-find/cgroup.procs
- 配置软限制,例如 2 MiB:
echo 2M >/sys/fs/cgroup/my-find/memory.high
找到正确的值需要调整和试验。您可以从memory.current
和/或获取当前值memory.stat
。随着时间的推移,您应该会看到high
增加memory.events
,因为 Linux 内核现在反复强制缩小缓存。
附录
请注意,该限制适用两个都用户空间内存和内核内存。它也适用于全部该组的进程,包括由 启动的子进程updatedb
,它基本上执行find | sort | frcode
,其中:
find
是程序破坏了dentry
和inode
缓存,这是我们想要限制的。否则它的用户空间内存需求(理论上)是恒定的。sort
需要大量内存,否则它将回退到使用临时文件,这将导致额外的 IO。frcode
将结果写入磁盘 - 例如单个文件 - 这需要恒定的内存。
所以基本上你应该只放入find
一个单独的cgroup
以限制其缓存垃圾,但不应该放入sort
和frcode
。
后经文
它不起作用,cgroup v1
因为设置memory.kmem.limit_in_bytes
已被弃用,并且一旦进程超过配置的限制,就会导致“内存不足”事件,这会立即终止您的进程,而不是强制 Linux 内核缩小内存使用量通过删除旧数据。引用部分配置_MEMCG_KMEM
目前内核内存没有实现软限制。未来的工作是在达到这些限制时触发板回收。
答案2
如果你看一下内核的inode源代码,您可以看到 ihash_entries 仅在内核级别设置。
根本没有用户或进程级别的考虑。添加这些可能会大大降低性能,从而适得其反。
它还意味着跟踪使用缓存条目的所有进程,因此使用更多内存来完成此操作。
最重要的是,当前内核根本不可能实现它,实现它也不是一个好主意。