我们今天遇到了一个有趣的错误。在我们的服务器上,我们将用户放入 cgroup 文件夹中,以监控和控制 CPU 和内存等资源的使用。我们在尝试添加用户特定的内存 cgroup 文件夹时开始出现错误:
mkdir /sys/fs/cgroup/memory/users/newuser
mkdir: cannot create directory ‘/sys/fs/cgroup/memory/users/newusers’: Cannot allocate memory
Run Code Online (Sandbox Code Playgroud)
这看起来有点奇怪,因为这台机器实际上有合理数量的空闲内存和交换区。将 的sysctl值vm.overcommit_memory从 0更改为 1 没有效果。
我们确实注意到我们运行了很多特定于用户的子文件夹(实际上大约有 7,000 个),其中大部分是为不再在该机器上运行进程的用户准备的。
ls /sys/fs/cgroup/memory/users/ | wc -l
7298
Run Code Online (Sandbox Code Playgroud)
删除 cgroup 层次结构中未使用的文件夹实际上解决了问题
cd /sys/fs/cgroup/memory/users/
ls | xargs -n1 rmdir
# errors for folders in-use, succeeds for unused
mkdir /sys/fs/cgroup/memory/users/newuser
# now works fine
Run Code Online (Sandbox Code Playgroud)
有趣的是,这个问题只影响了内存 cgroup。cpu/accounting cgroup 很好,即使它实际上在层次结构中有更多用户:
ls /sys/fs/cgroup/cpu,cpuacct/users/ | wc -l
7450
mkdir /sys/fs/cgroup/cpu,cpuacct/users/newuser
# fine
Run Code Online (Sandbox Code Playgroud)
那么,是什么导致了这些内存不足错误?memory-cgroup 子系统本身是否有某种内存限制?
cgroup 挂载的内容可以在这里找到
每个 cgroup 确实有限制,您可以在 LWN.net 上阅读有关它们的信息:
每个 cgroup 都有一个与其关联的内存控制器特定数据结构 (mem_cgroup)。
.... 记账按 cgroup 进行。
最大内存量存储在/sys/fs/cgroup/memory/memory.limit_in_bytes中。如果您遇到的问题确实与cgroup内存限制有关,那么/sys/fs/cgroup/memory/memory.max_usage_in_bytes应该接近上面的内容,您也可以通过检查memory.failcnt来检查来检查,它记录了次数您的实际使用量已达到上述限制。
也许您还可以检查memory.kmem.failcnt和memory.kmem.tcp.failcnt以获取有关内核内存和 tcp 缓冲区内存的类似统计信息。