Red Hat Training
A Red Hat training course is available for RHEL 8
24.2. 为 CPU 时间分布准备 cgroup
要控制应用程序的 CPU 消耗,您需要启用特定的 CPU 控制器,并创建一个专用的控制组。建议您在 /sys/fs/cgroup/
根控制组群中至少创建两级子控制组,以更好地保持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
控制器非常重要。重要cpu
控制器只有在相关子控制组至少有 2 个在单个 CPU 上竞争时间的进程时,才会被激活 。
验证步骤
可选:确保为直接子 cgroups 启用了与 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
其它资源
- 什么是控制组
- 什么是内核资源控制器
- 挂载 cgroups-v2
-
cgroups(7)
、sysfs(5)
手册页