24.2. 为 CPU 时间分布准备 cgroup
启用 CPU 控制器并创建专用控制组来管理应用程序 CPU 消耗。对于更好的机构,在 /sys/fs/cgroup/ 目录中至少建立两级子控制组。
先决条件
- 您有 root 权限。
- 您已确定了要控制的进程的 PID。
-
您已挂载了
cgroups-v2文件系统。如需更多信息,请参阅 挂载 cgroups-v2。
流程
识别您要限制其 CPU 消耗的应用程序的进程 ID(PID):
# top Tasks: 104 total, 3 running, 101 sleeping, 0 stopped, 0 zombie %Cpu(s): 17.6 us, 81.6 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.8 hi, 0.0 si, 0.0 st MiB Mem : 3737.4 total, 3312.7 free, 133.3 used, 291.4 buff/cache MiB Swap: 4060.0 total, 4060.0 free, 0.0 used. 3376.1 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 34578 root 20 0 18720 1756 1468 R 99.0 0.0 0:31.09 sha1sum 34579 root 20 0 18720 1772 1480 R 99.0 0.0 0:30.54 sha1sum 1 root 20 0 186192 13940 9500 S 0.0 0.4 0:01.60 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd 3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_par_gp ...示例输出显示
PID 34578和34579(sha1sum的两个图形应用程序)消耗大量资源,即 CPU。这两个应用程序都是用于演示cgroups-v2功能管理的示例应用程序。验证
/sys/fs/cgroup/cgroup.controllers文件中是否提供了cpu和cpuset控制器:# cat /sys/fs/cgroup/cgroup.controllers cpuset cpu io memory hugetlb pids rdma启用与 CPU 相关的控制器:
# echo "+cpu" >> /sys/fs/cgroup/cgroup.subtree_control # echo "+cpuset" >> /sys/fs/cgroup/cgroup.subtree_control这些命令为
/sys/fs/cgroup/根控制组的直接子组启用了cpu和cpuset控制器。子组 是您可以指定进程,并根据您的标准对每个进程应用控制检查的地方。您可以在任何级别上查看
cgroup.subtree_control文件,以识别可在直接子组中启用的控制器。注意默认情况下,根控制组中的
/sys/fs/cgroup/cgroup.subtree_control文件包含memory和pids控制器。创建
/sys/fs/cgroup/Example/目录:# mkdir /sys/fs/cgroup/Example//sys/fs/cgroup/Example/目录定义了一个子组。此外,上一步为这个子组启用了cpu和cpuset控制器。创建
/sys/fs/cgroup/Example/目录时,一些cgroups-v2接口文件以及cpu和cpuset特定于控制器的文件也会在目录中自动创建。/sys/fs/cgroup/Example/目录还为memory和pids控制器提供特定于控制器的文件。可选:检查新创建的子控制组:
# ll /sys/fs/cgroup/Example/ -r—r—r--. 1 root root 0 Jun 1 10:33 cgroup.controllers -r—r—r--. 1 root root 0 Jun 1 10:33 cgroup.events -rw-r—r--. 1 root root 0 Jun 1 10:33 cgroup.freeze -rw-r—r--. 1 root root 0 Jun 1 10:33 cgroup.max.depth -rw-r—r--. 1 root root 0 Jun 1 10:33 cgroup.max.descendants -rw-r—r--. 1 root root 0 Jun 1 10:33 cgroup.procs -r—r—r--. 1 root root 0 Jun 1 10:33 cgroup.stat -rw-r—r--. 1 root root 0 Jun 1 10:33 cgroup.subtree_control … -rw-r—r--. 1 root root 0 Jun 1 10:33 cpuset.cpus -r—r—r--. 1 root root 0 Jun 1 10:33 cpuset.cpus.effective -rw-r—r--. 1 root root 0 Jun 1 10:33 cpuset.cpus.partition -rw-r—r--. 1 root root 0 Jun 1 10:33 cpuset.mems -r—r—r--. 1 root root 0 Jun 1 10:33 cpuset.mems.effective -r—r—r--. 1 root root 0 Jun 1 10:33 cpu.stat -rw-r—r--. 1 root root 0 Jun 1 10:33 cpu.weight -rw-r—r--. 1 root root 0 Jun 1 10:33 cpu.weight.nice … -r—r—r--. 1 root root 0 Jun 1 10:33 memory.events.local -rw-r—r--. 1 root root 0 Jun 1 10:33 memory.high -rw-r—r--. 1 root root 0 Jun 1 10:33 memory.low … -r—r—r--. 1 root root 0 Jun 1 10:33 pids.current -r—r—r--. 1 root root 0 Jun 1 10:33 pids.events -rw-r—r--. 1 root root 0 Jun 1 10:33 pids.max示例输出显示
cpuset.cpus和cpu.max等文件。这些文件特定于cpuset和cpu控制器。使用/sys/fs/cgroup/cgroup.subtree_control文件,为根的(/sys/fs/cgroup/)直接子控制组 手动启用cpuset和cpu控制器。目录还包含通用
cgroup控制接口文件,如cgroup.procs或cgroup.controllers,它们对所有控制组都通用,无论启用的控制器是什么。memory.high和pids.max等文件与memory和pids控制器有关,它们位于根控制组中(/sys/fs/cgroup/),默认情况下总是启用的。默认情况下,新创建的子组继承了对系统所有 CPU 和内存资源的访问权限,没有任何限制。
启用
/sys/fs/cgroup/Example/中与 CPU 相关的控制器,以获取仅与 CPU 相关的控制器:# echo "+cpu" >> /sys/fs/cgroup/Example/cgroup.subtree_control # echo "+cpuset" >> /sys/fs/cgroup/Example/cgroup.subtree_control这些命令确保直接子控制组将 只能 有与控制 CPU 时间相关的控制器,而不是
memory或pids控制器。创建
/sys/fs/cgroup/Example/tasks/目录:# mkdir /sys/fs/cgroup/Example/tasks//sys/fs/cgroup/Example/tasks/目录定义了一个子组,以及只与cpu和cpuset控制器相关的文件。可选:检查另一个子控制组群:
# ll /sys/fs/cgroup/Example/tasks -r—r—r--. 1 root root 0 Jun 1 11:45 cgroup.controllers -r—r—r--. 1 root root 0 Jun 1 11:45 cgroup.events -rw-r—r--. 1 root root 0 Jun 1 11:45 cgroup.freeze -rw-r—r--. 1 root root 0 Jun 1 11:45 cgroup.max.depth -rw-r—r--. 1 root root 0 Jun 1 11:45 cgroup.max.descendants -rw-r—r--. 1 root root 0 Jun 1 11:45 cgroup.procs -r—r—r--. 1 root root 0 Jun 1 11:45 cgroup.stat -rw-r—r--. 1 root root 0 Jun 1 11:45 cgroup.subtree_control -rw-r—r--. 1 root root 0 Jun 1 11:45 cgroup.threads -rw-r—r--. 1 root root 0 Jun 1 11:45 cgroup.type -rw-r—r--. 1 root root 0 Jun 1 11:45 cpu.max -rw-r—r--. 1 root root 0 Jun 1 11:45 cpu.pressure -rw-r—r--. 1 root root 0 Jun 1 11:45 cpuset.cpus -r—r—r--. 1 root root 0 Jun 1 11:45 cpuset.cpus.effective -rw-r—r--. 1 root root 0 Jun 1 11:45 cpuset.cpus.partition -rw-r—r--. 1 root root 0 Jun 1 11:45 cpuset.mems -r—r—r--. 1 root root 0 Jun 1 11:45 cpuset.mems.effective -r—r—r--. 1 root root 0 Jun 1 11:45 cpu.stat -rw-r—r--. 1 root root 0 Jun 1 11:45 cpu.weight -rw-r—r--. 1 root root 0 Jun 1 11:45 cpu.weight.nice -rw-r—r--. 1 root root 0 Jun 1 11:45 io.pressure -rw-r—r--. 1 root root 0 Jun 1 11:45 memory.pressure确保您要控制 CPU 时间的进程在同一 CPU 上竞争:
# echo "1" > /sys/fs/cgroup/Example/tasks/cpuset.cpus这样可确保您将放入
Example/tasks子控制组中的进程,在同一 CPU 上竞争。此设置对于要激活的cpu控制器非常重要。重要只有在相关子组至少有 2 个进程在单个 CPU 上竞争时,才会激活
cpu控制器。
验证
可选:确保为直接子 cgroup 启用与 CPU 相关的控制器:
# cat /sys/fs/cgroup/cgroup.subtree_control /sys/fs/cgroup/Example/cgroup.subtree_control cpuset cpu memory pids cpuset cpu可选:确保您要控制 CPU 时间的进程在同一 CPU 上竞争:
# cat /sys/fs/cgroup/Example/tasks/cpuset.cpus 1