使用 cgroups-v1 为应用程序设置 CPU 限制

2023-03-31 13:42:24 浏览数 (1)

有时应用会占用大量 CPU 时间,这可能会对环境的整体健康状况造成负面影响。使用 /sys/fs/ 虚拟文件系统,利用 控制组版本 1 (cgroups-v1) 为应用配置 CPU 限制。

先决条件

  • 您有 root 权限。
  • 您有一个应用程序,您想限制其 CPU 消耗。
  • 验证是否已挂载了 cgroups-v1 控制器:
代码语言:javascript复制
# mount -l | grep cgroup
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,seclabel,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpu,cpuacct)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,perf_event)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,pids)
...

流程

  1. 在 CPU 消耗中识别您要限制的应用程序的进程 ID (PID):
代码语言:javascript复制
# top
top - 11:34:09 up 11 min,  1 user,  load average: 0.51, 0.27, 0.22
Tasks: 267 total,   3 running, 264 sleeping,   0 stopped,   0 zombie
%Cpu(s): 49.0 us,  3.3 sy,  0.0 ni, 47.5 id,  0.0 wa,  0.2 hi,  0.0 si,  0.0 st
MiB Mem :   1826.8 total,    303.4 free,   1046.8 used,    476.5 buff/cache
MiB Swap:   1536.0 total,   1396.0 free,    140.0 used.    616.4 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME  COMMAND
 6955 root      20   0  228440   1752   1472 R  99.3   0.1   0:32.71 sha1sum
 5760 jdoe      20   0 3603868 205188  64196 S   3.7  11.0   0:17.19 gnome-shell
 6448 jdoe      20   0  743648  30640  19488 S   0.7   1.6   0:02.73 gnome-terminal-
    1 root      20   0  245300   6568   4116 S   0.3   0.4   0:01.87 systemd
  505 root      20   0       0      0      0 I   0.3   0.0   0:00.75 kworker/u4:4-events_unbound
...

top 程序的输出示例显示 PID 6955 (应用 sha1sum)消耗了大量 CPU 资源。

cpu 资源控制器目录中创建子目录:

代码语言:javascript复制
mkdir /sys/fs/cgroup/cpu/Example/

上面的目录代表控制组,您可以在其中放置特定进程并将某些 CPU 限制应用到进程。同时,目录中将创建一些 cgroups-v1 接口文件和 cpu 控制器特定的文件。

(可选)检查新创建的控制组群:

代码语言:javascript复制
# ll /sys/fs/cgroup/cpu/Example/
-rw-r—​r--. 1 root root 0 Mar 11 11:42 cgroup.clone_children
-rw-r—​r--. 1 root root 0 Mar 11 11:42 cgroup.procs
-r—​r—​r--. 1 root root 0 Mar 11 11:42 cpuacct.stat
-rw-r—​r--. 1 root root 0 Mar 11 11:42 cpuacct.usage
-r—​r—​r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_all
-r—​r—​r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_percpu
-r—​r—​r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_percpu_sys
-r—​r—​r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_percpu_user
-r—​r—​r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_sys
-r—​r—​r--. 1 root root 0 Mar 11 11:42 cpuacct.usage_user
-rw-r—​r--. 1 root root 0 Mar 11 11:42 cpu.cfs_period_us
-rw-r—​r--. 1 root root 0 Mar 11 11:42 cpu.cfs_quota_us
-rw-r—​r--. 1 root root 0 Mar 11 11:42 cpu.rt_period_us
-rw-r—​r--. 1 root root 0 Mar 11 11:42 cpu.rt_runtime_us
-rw-r—​r--. 1 root root 0 Mar 11 11:42 cpu.shares
-r—​r—​r--. 1 root root 0 Mar 11 11:42 cpu.stat
-rw-r—​r--. 1 root root 0 Mar 11 11:42 notify_on_release
-rw-r—​r--. 1 root root 0 Mar 11 11:42 tasks

示例输出中显示的文件,如 cpuacct.usagecpu.cfs._period_us,它们代表特定配置和/或限制,可以为 Example 控制组中的进程设置。请注意,对应的文件名前缀为它们所属的控制组控制器的名称。

默认情况下,新创建的控制组继承对系统整个 CPU 资源的访问权限,且无限制。

为控制组群配置 CPU 限制:

代码语言:javascript复制
echo "1000000" > /sys/fs/cgroup/cpu/Example/cpu.cfs_period_us
echo "200000" > /sys/fs/cgroup/cpu/Example/cpu.cfs_quota_us

cpu.cfs_period_us 文件表示以微秒为单位(这里表示为"us")的时段,用于控制组对 CPU 资源的访问权限应重新分配的频率。上限为 1 秒,下限为 1000 微秒。

cpu.cfs_quota_us 文件表示以微秒为单位的总时间量,控制组中的所有进程都可以在一个期间(如 cpu.cfs_period_us 定义)。当控制组中的进程在单个期间内使用配额指定的所有时间时,就会在句点的其余部分内进行限流,并且不允许在下一个期间内运行。下限为 1000 微秒。

上面的示例命令设定 CPU 时间限值,使得 Example 控制组中的所有进程仅能每 1 秒( cpu.cfs_quota_us 定义)每 1 秒(由 cpu.cfs_period_us 定义)运行 0.2 秒。

另外,还可验证限制:

代码语言:javascript复制
# cat /sys/fs/cgroup/cpu/Example/cpu.cfs_period_us /sys/fs/cgroup/cpu/Example/cpu.cfs_quota_us
1000000
200000

将应用程序的 PID 添加到 Example 控制组群中:

代码语言:javascript复制
# echo "6955" > /sys/fs/cgroup/cpu/Example/cgroup.procs

or

# echo "6955" > /sys/fs/cgroup/cpu/Example/tasks

上一命令可确保所需的应用成为 Example 控制组的成员,因此不超过为 Example 控制组配置的 CPU 限值。PID 应该代表系统中的一个已存在的进程。这里的 PID 6955 分配给进程 sha1sum /dev/zero &,用于演示 cpu 控制器的用例。

验证应用程序是否在指定的控制组群中运行:

代码语言:javascript复制
# cat /proc/6955/cgroup
12:cpuset:/
11:hugetlb:/
10:net_cls,net_prio:/
9:memory:/user.slice/user-1000.slice/user@1000.service
8:devices:/user.slice
7:blkio:/
6:freezer:/
5:rdma:/
4:pids:/user.slice/user-1000.slice/user@1000.service
3:perf_event:/
2:cpu,cpuacct:/Example
1:name=systemd:/user.slice/user-1000.slice/user@1000.service/gnome-terminal-server.service

上面的示例输出显示所需应用的进程在 Example 控制组中运行,它将 CPU 限制应用到应用的进程。

确定节流应用程序的当前 CPU 消耗:

代码语言:javascript复制
# top
top - 12:28:42 up  1:06,  1 user,  load average: 1.02, 1.02, 1.00
Tasks: 266 total,   6 running, 260 sleeping,   0 stopped,   0 zombie
%Cpu(s): 11.0 us,  1.2 sy,  0.0 ni, 87.5 id,  0.0 wa,  0.2 hi,  0.0 si,  0.2 st
MiB Mem :   1826.8 total,    287.1 free,   1054.4 used,    485.3 buff/cache
MiB Swap:   1536.0 total,   1396.7 free,    139.2 used.    608.3 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME  COMMAND
 6955 root      20   0  228440   1752   1472 R  20.6   0.1  47:11.43 sha1sum
 5760 jdoe      20   0 3604956 208832  65316 R   2.3  11.2   0:43.50 gnome-shell
 6448 jdoe      20   0  743836  31736  19488 S   0.7   1.7   0:08.25 gnome-terminal-
  505 root      20   0       0      0      0 I   0.3   0.0   0:03.39 kworker/u4:4-events_unbound
 4217 root      20   0   74192   1612   1320 S   0.3   0.1   0:01.19 spice-vdagentd
...

请注意,PID 6955 的 CPU 消耗从 99% 降至 20%。

本文为从大数据到人工智能博主「xiaozhch5」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://cloud.tencent.com/developer/article/2255259

0 人点赞