深入理解 Linux Cgroup 系列(三):内存
原文链接:深入理解 Linux Cgroup 系列(三):内存 通过上篇文章的学习,我们学会了如何查看当前 cgroup 的信息,如何通过操作 1. 寻找走失内存上篇文章告诉我们,CPU controller 提供了两种方法来限制 CPU 使用时间,其中 对于内存而言,在 CentOS 7 中,systemd 已经帮我们将 memory 绑定到了 /sys/fs/cgroup/memory。 $ systemctl set-property user-1000.slice MemoryLimit=200M 现在使用用户 $ stress --vm 8 --vm-bytes 256M 按照预想,stress 进程的内存使用量已经超出了限制,此时应该会触发 $ cd /sys/fs/cgroup/memory/user.slice/user-1000.slice $ cat memory.usage_in_bytes 209661952 奇怪,占用的内存还不到 200M,剩下的内存都跑哪去了呢?别慌,你是否还记得 linux 系统中的内存使用除了包括物理内存,还包括交换分区,也就是 swap,我们来看看是不是 swap 搞的鬼。先停止刚刚的 stress 进程,稍等 30 秒,观察一下 swap 空间的占用情况: $ free -h total used free shared buff/cache available Mem: 3.7G 180M 3.2G 8.9M 318M 3.3G Swap: 3.9G 512K 3.9G 重新运行 stress 进程: $ stress --vm 8 --vm-bytes 256M 查看内存使用情况: $ cat memory.usage_in_bytes 209637376 发现内存占用刚好在 200M 以内。再看 swap 空间占用情况: $ free total used free shared buff/cache available Mem: 3880876 407464 3145260 9164 328152 3220164 Swap: 4063228 2031360 2031868 和刚刚相比,多了 $ egrep "swap|rss" memory.stat rss 209637376 rss_huge 0 swap 1938804736 total_rss 209637376 total_rss_huge 0 total_swap 1938804736 可以看到物理内存使用量为 这个时候如果你每隔几秒就查看一次 $ cat memory.failcnt 59390293 从上面的结果可以看出,当物理内存不够时,就会触发 memory.failcnt 里面的数量加 1,但此时进程不一定会被杀死,内核会尽量将物理内存中的数据移动到 swap 空间中。 2. 关闭 swap为了更好地观察 cgroup 对内存的控制,我们可以用户 tom 不使用 swap 空间,实现方法有以下几种:
如果你既不想关闭系统的交换空间,又想让 tom 不使用 swap 空间,上面给出的第一个方法是有问题的:
如果按照常规思路去解决这个问题,可能会非常棘手,我们可以另辟蹊径,从 PAM 入手。 Linux PAM(Pluggable Authentication Modules) 是一个系统级用户认证框架,PAM 将程序开发与认证方式进行分离,程序在运行时调用附加的“认证”模块完成自己的工作。本地系统管理员通过配置选择要使用哪些认证模块,其中 从 $ cat /usr/local/bin/tom-noswap.sh #!/bin/bash if [ $PAM_USER == ‘tom‘ ] then echo 0 > /sys/fs/cgroup/memory/user.slice/user-1000.slice/memory.swappiness fi 然后在 $ session optional pam_exec.so seteuid /usr/local/bin/tom-noswap.sh 现在再使用 tom 用户登录,就会发现
3. 控制内存使用关闭了 swap 之后,我们就可以严格控制进程的内存使用量了。还是使用开头提到的例子,使用用户 tom 登录该系统,先在第一个 shell 窗口运行以下命令: $ journalctl -f 打开第二个 shell 窗口(还是 tom 用户),通过 stress 命令产生 8 个子进程,每个进程分配 256M 内存: $ stress --vm 8 --vm-bytes 256M stress: info: [30150] dispatching hogs: 0 cpu,0 io,8 vm,0 hdd stress: FAIL: [30150] (415) <-- worker 30152 got signal 9 stress: WARN: [30150] (417) stress: FAIL: [30150] (415) <-- worker 30151 got signal 9 stress: WARN: [30150] (417) now reaping child worker processes stress: FAIL: [30150] (415) <-- worker 30154 got signal 9 stress: WARN: [30150] (417) now reaping child worker processes stress: FAIL: [30150] (415) <-- worker 30157 got signal 9 stress: WARN: [30150] (417) now reaping child worker processes stress: FAIL: [30150] (415) <-- worker 30158 got signal 9 stress: WARN: [30150] (417) now reaping child worker processes stress: FAIL: [30150] (451) failed run completed in 0s 现在可以看到 stress 进程很快被 kill 掉了,回到第一个 shell 窗口,会输出以下信息: 由此可见 cgroup 对内存的限制奏效了,stress 进程的内存使用量超出了限制,触发了 oom-killer,进而杀死进程。 4. 更多文档加个小插曲,如果你想获取更多关于 cgroup 的文档,可以通过 yum 安装 $ cd /usr/share/doc/kernel-doc-3.10.0/Documentation/cgroups $ ll 总用量 172 4 -r--r--r-- 1 root root 918 6月 14 02:29 00-INDEX 16 -r--r--r-- 1 root root 16355 6月 14 02:29 blkio-controller.txt 28 -r--r--r-- 1 root root 27027 6月 14 02:29 cgroups.txt 4 -r--r--r-- 1 root root 1972 6月 14 02:29 cpuacct.txt 40 -r--r--r-- 1 root root 37225 6月 14 02:29 cpusets.txt 8 -r--r--r-- 1 root root 4370 6月 14 02:29 devices.txt 8 -r--r--r-- 1 root root 4908 6月 14 02:29 freezer-subsystem.txt 4 -r--r--r-- 1 root root 1714 6月 14 02:29 hugetlb.txt 16 -r--r--r-- 1 root root 14124 6月 14 02:29 memcg_test.txt 36 -r--r--r-- 1 root root 36415 6月 14 02:29 memory.txt 4 -r--r--r-- 1 root root 1267 6月 14 02:29 net_cls.txt 4 -r--r--r-- 1 root root 2513 6月 14 02:29 net_prio.txt 下一篇文章将会讨论如何使用 cgroup 来限制 I/O,敬请期待~(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |