通过上篇文章的学习,我们学会了如何查看当前 cgroup 的信息,如何通过操作 /sys/fs/cgroup
目录来动态设置 cgroup,也学会了如何设置 CPU shares 和 CPU quota 来控制 slice
内部以及不同 slice
之间的 CPU 使用时间。本文将把重心转移到内存上,通过具体的示例来演示如何通过 cgroup 来限制内存的使用。
1. 寻找走失内存
上篇文章告诉我们,CPU controller 提供了两种方法来限制 CPU 使用时间,其中 CPUShares
用来设置相对权重,CPUQuota
用来限制 user、service 或 VM 的 CPU 使用时间百分比。例如:如果一个 user 同时设置了 CPUShares 和 CPUQuota,假设 CPUQuota 设置成 50%
,那么在该 user 的 CPU 使用量达到 50% 之前,可以一直按照 CPUShares 的设置来使用 CPU。
对于内存而言,在 CentOS 7 中,systemd 已经帮我们将 memory 绑定到了 /sys/fs/cgroup/memory。systemd
只提供了一个参数 MemoryLimit
来对其进行控制,该参数表示某个 user 或 service 所能使用的物理内存总量。拿之前的用户 tom 举例, 它的 UID 是 1000,可以通过以下命令来设置:
$ systemctl set-property user-1000.slice MemoryLimit=200M
现在使用用户 tom
登录该系统,通过 stress
命令产生 8 个子进程,每个进程分配 256M 内存:
$ stress --vm 8 --vm-bytes 256M
按照预想,stress 进程的内存使用量已经超出了限制,此时应该会触发 oom-killer
,但实际上进程仍在运行,这是为什么呢?我们来看一下目前占用的内存:
$ 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 availa