写在前面
- 考试整理,分享一些Linux CPU时间分布配置的笔记
- 内容涉及 CPU
带宽
,权重
,亲和性
配置前后测试Demo - Deom 主要以
进程级别
使用Cgroup-v2
实现 服务级别
使用systyemd
简单介绍- 理解不足小伙伴帮忙指正 :) 生活加油
我所渴求的,無非是將心中脫穎語出的本性付諸生活,為何竟如此艱難呢 -----赫尔曼·黑塞《德米安》
为什么需要对 CPU 时间分布进行配置
在多用户或多任务系统中,合理地分配CPU资源
可以确保每个任务或用户都能获得足够的计算资源,从而提高整体的系统性能。如果一个应用程序占用了过多的CPU时间,它可能会降低其他应用程序或服务的性能
。
通过限制应用程序的CPU时间分布
,可以确保不同的任务或用户之间获得公平的CPU资源
。这有助于防止某些应用程序或用户占用过多资源,导致其他任务或用户无法获得足够的CPU时间。
同时,在某些情况下,你可能希望将某个应用程序或服务与系统中的其他部分隔离开来
。通过限制其CPU资源(亲和性配置)
,你可以确保该应用程序或服务不会对其他部分产生过大的影响,即使它出现性能问题或异常行为。又或者是CPU 资源有限,希望负责核心业务的程序希望获取更多的CPU时间片轮(CPU权重
),对于一些辅助程序,不希望占用更多的CPU 资源(权重)
虽然 CPU 属于可压缩资源
,但是任然要避免资源耗尽,如果一个应用程序占用了过多的CPU时间,它可能会导致系统资源耗尽,例如CPU使用率过高、内存不足等。这可能会导致系统变得不稳定、响应缓慢或完全崩溃。通过限制CPU 带宽
,可以降低这种风险。
今天和小伙伴分享 通过 cgroups-v2
来实现应用程序 CPU 时间分布的配置,从而控制应用程序的 CPU 消耗。这里的配置主要有三种方法:
设置CPU 亲和性
:限定控制组的进程或者服务仅使用分配的CPU
设置CPU带宽
:限定控制组的进程每秒可以在CPU上运行多少秒
设置CPU权重
:限定控制组的进程在 CPU上多个应用程序使用CPU占比
实验环境
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$hostnamectl
Static hostname: vms99.liruilongs.github.io
Icon name: computer-vm
Chassis: vm
Machine ID: ea70bf6266cb413c84266d4153276342
Boot ID: 2333fe6d930148d59327b9fd9ce48c37
Virtualization: vmware
Operating System: Rocky Linux 8.9 (Green Obsidian)
CPE OS Name: cpe:/o:rocky:rocky:8:GA
Kernel: Linux 4.18.0-513.9.1.el8_9.x86_64
Architecture: x86-64
┌──[root@vms99.liruilongs.github.io]-[~]
└─$
cgroups-v2 配置
cgroups-v2 设置CPU 亲和性Demo
确认 Cgroup 版本
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$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/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,freezer)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpuset)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,pids)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,cpu,cpuacct)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,hugetlb)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,perf_event)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,devices)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,net_cls,net_prio)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,memory)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,blkio)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,seclabel,rdma)
Rocky Linux 8.9
默认挂载 cgroup-v1 虚拟文件系统。要利用 cgroup-v2 功能限制应用程序的资源,需要手动配置系统。通过 systemd
系统和服务管理器系统,在系统引导期间将系统配置为默认挂载 cgroups-v2 :
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="systemd.unified_cgroup_hierarchy=1"
这会向当前引导条目中添加必要的内核命令行参数。向所有内核引导条目中添加 systemd.unified_cgroup_hierarchy=1
参数:
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"
重启系统以使更改生效。
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$reboot
Connection to 192.168.26.99 closed by remote host.
Connection to 192.168.26.99 closed.
代码语言:javascript复制PS C:UsersAdministrator> ssh root@192.168.26.99
root@192.168.26.99's password:
Web console: https://vms99.liruilongs.github.io:9090/ or https://192.168.26.99:9090/
Last login: Sat May 11 03:13:30 2024 from 192.168.26.1
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$mount -l | grep cgroup
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,seclabel,nsdelegate)
┌──[root@vms99.liruilongs.github.io]-[~]
└─$
cgroups-v2
文件系统已成功挂载到 /sys/fs/cgroup/
目录。
检查 /sys/fs/cgroup/
目录的内容:
/sys/fs/cgroup/
目录也称为 根控制组
,默认情况下,包含接口文件(以 cgroup 开头)和特定于控制器的文件,如 cpuset.cpus.effective
。此外,还有一些与 systemd
相关的目录,如 /sys/fs/cgroup/init.scope
、/sys/fs/cgroup/system.slice
和 /sys/fs/cgroup/user.slice
┌──[root@vms99.liruilongs.github.io]-[~]
└─$ll /sys/fs/cgroup/
总用量 0
-r--r--r--. 1 root root 0 5月 15 20:29 cgroup.controllers
-rw-r--r--. 1 root root 0 5月 15 20:29 cgroup.max.depth
-rw-r--r--. 1 root root 0 5月 15 20:29 cgroup.max.descendants
-rw-r--r--. 1 root root 0 5月 15 20:29 cgroup.procs
-r--r--r--. 1 root root 0 5月 15 20:29 cgroup.stat
-rw-r--r--. 1 root root 0 5月 15 20:29 cgroup.subtree_control
-rw-r--r--. 1 root root 0 5月 15 20:29 cgroup.threads
-r--r--r--. 1 root root 0 5月 15 20:29 cpuset.cpus.effective
-r--r--r--. 1 root root 0 5月 15 20:29 cpuset.mems.effective
-r--r--r--. 1 root root 0 5月 15 20:29 cpu.stat
drwxr-xr-x. 2 root root 0 5月 15 20:29 init.scope
-r--r--r--. 1 root root 0 5月 15 20:29 io.stat
drwxr-xr-x. 2 root root 0 5月 15 20:29 machine.slice
-r--r--r--. 1 root root 0 5月 15 20:29 memory.numa_stat
--w-------. 1 root root 0 5月 15 20:29 memory.reclaim
-r--r--r--. 1 root root 0 5月 15 20:29 memory.stat
drwxr-xr-x. 85 root root 0 5月 15 20:29 system.slice
drwxr-xr-x. 3 root root 0 5月 15 21:23 user.slice
┌──[root@vms99.liruilongs.github.io]-[~]
└─$
为 CPU 时间分布准备 cgroup
,要控制应用程序的 CPU 消耗,您需要启用特定的 CPU 控制器,并创建一个专用的控制组。一般建议在 /sys/fs/cgroup/
根控制组群中至少创建两级子控制组
,以更好地保持 cgroup
文件的组织清晰性。
在 cgroup v2 中,可以通过 cpuset.cpus.effective
和 cpuset.mems.effective
等只读文件来查看 cgroup 当前可以访问的 CPU 和内存资源,但这些文件是只读的
,不能直接修改它们来设置 CPU 核心或内存节点的分配
┌──[root@vms99.liruilongs.github.io]-[~]
└─$ll /sys/fs/cgroup/cpu*
-r--r--r--. 1 root root 0 5月 15 20:29 /sys/fs/cgroup/cpuset.cpus.effective
-r--r--r--. 1 root root 0 5月 15 20:29 /sys/fs/cgroup/cpuset.mems.effective
-r--r--r--. 1 root root 0 5月 15 20:29 /sys/fs/cgroup/cpu.stat
给 当前父级对应的子 Cgroup 层级添加 cpu 相关的控制器
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$echo " cpu" >> /sys/fs/cgroup/cgroup.subtree_control
┌──[root@vms99.liruilongs.github.io]-[~]
└─$echo " cpuset" >> /sys/fs/cgroup/cgroup.subtree_control
┌──[root@vms99.liruilongs.github.io]-[~]
└─$cat /sys/fs/cgroup/cgroup.subtree_control
cpuset cpu memory pids
创建 Example 控制组
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$mkdir /sys/fs/cgroup/Example/
给 Example 的子级添加 cpu 相关控制器
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$cat /sys/fs/cgroup/Example/cgroup.controllers
cpuset cpu memory pids
┌──[root@vms99.liruilongs.github.io]-[~]
└─$echo " cpu" >> /sys/fs/cgroup/Example/cgroup.subtree_control
┌──[root@vms99.liruilongs.github.io]-[~]
└─$echo " cpuset" >> /sys/fs/cgroup/Example/cgroup.subtree_control
┌──[root@vms99.liruilongs.github.io]-[~]
└─$cat /sys/fs/cgroup/Example/cgroup.subtree_control
cpuset cpu
创建一个 tasks
组,这里我们用于测试亲和性
┌──[root@vms99.liruilongs.github.io]-[~]
└─$mkdir /sys/fs/cgroup/Example/tasks/
┌──[root@vms99.liruilongs.github.io]-[~]
└─$cat /sys/fs/cgroup/Example/tasks/cgroup.controllers
cpuset cpu
┌──[root@vms99.liruilongs.github.io]-[~]
└─$echo "1" > /sys/fs/cgroup/Example/tasks/cpuset.cpus
未配置亲和性
这里以 httpd 服务为Demo,当没有配置亲和性时
启动服务
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$systemctl enable --now httpd
默认的亲和性是 所以的CPU,即可以使用任意 CPU
┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep httpd | xargs
1289 1456 1461 1466 1471
这里的掩码 111111
,表示当前 6个核心都可以使用。
┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep httpd | xargs -I {} taskset -p {}
pid 1289 的当前亲和力掩码:3f
pid 1456 的当前亲和力掩码:3f
pid 1461 的当前亲和力掩码:3f
pid 1466 的当前亲和力掩码:3f
pid 1471 的当前亲和力掩码:3f
┌──[root@vms99.liruilongs.github.io]-[~]
└─$python -c "print(format(0x3f,'032b'))"
00000000000000000000000000111111
确认当前 Cgroup
控制组
┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep httpd | xargs -I {} cat /proc/{}/cgroup
0::/system.slice/httpd.service
0::/system.slice/httpd.service
0::/system.slice/httpd.service
0::/system.slice/httpd.service
0::/system.slice/httpd.service
这里我们以 ab
命令模拟业务高峰
┌──[root@vms99.liruilongs.github.io]-[~]
└─$ab -n 100000 -c 10000 127.0.0.1:80/
┌──[root@vms99.liruilongs.github.io]-[~]
└─$ab -n 100000 -c 10000 127.0.0.1:80/
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
Completed 20000 requests
.........
Completed 100000 requests
通过 mpstat
观察每个CPU 核数使用率变化,CPU 列为 CPU 编号
,%idle
空闲率,%sys
,%usr
为系统态和用户态的 CPU 时间消耗
┌──[root@vms99.liruilongs.github.io]-[~]
└─$ mpstat -P ALL 2
Linux 4.18.0-513.9.1.el8_9.x86_64 (vms99.liruilongs.github.io) 2024年05月15日 _x86_64_ (6 CPU)
22时16分56秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
22时16分58秒 all 0.00 0.00 0.08 0.00 0.00 0.00 0.00 0.00 0.00 99.92
22时16分58秒 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时16分58秒 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时16分58秒 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时16分58秒 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时16分58秒 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时16分58秒 5 0.00 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 99.50
22时16分58秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
22时17分00秒 all 6.43 0.00 19.10 0.00 0.54 9.50 0.00 0.00 0.00 64.43
22时17分00秒 0 5.38 0.00 18.28 0.00 0.54 11.29 0.00 0.00 0.00 64.52
22时17分00秒 1 5.95 0.00 18.92 0.00 0.54 10.27 0.00 0.00 0.00 64.32
22时17分00秒 2 5.91 0.00 19.35 0.00 0.54 9.14 0.00 0.00 0.00 65.05
22时17分00秒 3 6.49 0.00 20.00 0.00 0.54 9.73 0.00 0.00 0.00 63.24
22时17分00秒 4 7.87 0.00 18.54 0.00 0.56 8.43 0.00 0.00 0.00 64.61
22时17分00秒 5 7.03 0.00 19.46 0.00 0.54 8.11 0.00 0.00 0.00 64.86
22时17分00秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
22时17分02秒 all 9.20 0.00 24.69 0.00 1.03 13.90 0.00 0.00 0.00 51.17
22时17分02秒 0 9.71 0.00 24.57 0.00 0.57 13.71 0.00 0.00 0.00 51.43
22时17分02秒 1 9.60 0.00 24.86 0.00 1.13 12.43 0.00 0.00 0.00 51.98
22时17分02秒 2 10.11 0.00 24.72 0.00 1.12 11.80 0.00 0.00 0.00 52.25
22时17分02秒 3 7.87 0.00 24.72 0.00 1.12 15.73 0.00 0.00 0.00 50.56
22时17分02秒 4 8.99 0.00 24.72 0.00 1.12 16.29 0.00 0.00 0.00 48.88
22时17分02秒 5 8.94 0.00 24.58 0.00 1.12 13.41 0.00 0.00 0.00 51.96
直接观察 %idle
空闲率即可
%idle
51.17
51.43
51.98
52.25
50.56
48.88
51.96
可以看到 每个CPU 在业务高峰期空闲率都着降低到 50%
左右,同时 用户态和系统态的 CPU 利用率增加,即所以核同时被使用
配置亲和性测试
这里我们配置tasks
对应的 Cgroup CPU 亲和性为 1,即只能使用 编号为 1 的CPU
┌──[root@vms99.liruilongs.github.io]-[~]
└─$echo "1" > /sys/fs/cgroup/Example/tasks/cpuset.cpus
┌──[root@vms99.liruilongs.github.io]-[~]
└─$cat /sys/fs/cgroup/Example/tasks/cpuset.cpus
1
把 httpd 的所有进程添加到上面配置亲和性的 tasks 组
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep httpd | xargs -I {} echo {} > /sys/fs/cgroup/Example/tasks/cgroup.procs
┌──[root@vms99.liruilongs.github.io]-[~]
└─$cat /sys/fs/cgroup/Example/tasks/cgroup.procs
1289
1456
1461
1466
1471
确实当前组的 Cpu相关控制器存在
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$cat /sys/fs/cgroup/cgroup.subtree_control /sys/fs/cgroup/Example/cgroup.subtree_control
cpuset cpu memory pids
cpuset cpu
重新查看 CPU 亲和性,发现已经改变
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep httpd | xargs -I {} taskset -p {}
pid 1289 的当前亲和力掩码:2
pid 1456 的当前亲和力掩码:2
pid 1461 的当前亲和力掩码:2
pid 1466 的当前亲和力掩码:2
pid 1471 的当前亲和力掩码:2
┌──[root@vms99.liruilongs.github.io]-[~]
└─$python -c "print(format(0x2,'032b'))"
00000000000000000000000000000010
┌──[root@vms99.liruilongs.github.io]-[~]
└─$
确认对应的 Cgroup 控制组也已经改变
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep httpd | xargs -I {} cat /proc/{}/cgroup
0::/Example/tasks
0::/Example/tasks
0::/Example/tasks
0::/Example/tasks
0::/Example/tasks
再次使用 ad 命令模拟业务高峰
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$ab -n 100000 -c 10000 127.0.0.1:80/
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
Completed 20000 requests
。。。。。。。。。
观察每个 cpu 的空闲率变化
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$mpstat -P ALL 2
Linux 4.18.0-513.9.1.el8_9.x86_64 (vms99.liruilongs.github.io) 2024年05月15日 _x86_64_ (6 CPU)
22时31分54秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
22时31分56秒 all 1.32 0.00 9.93 0.00 0.35 5.54 0.00 0.00 0.00 82.86
22时31分56秒 0 0.00 0.00 0.00 0.00 0.00 4.40 0.00 0.00 0.00 95.60
22时31分56秒 1 7.00 0.00 55.00 0.00 0.50 17.00 0.00 0.00 0.00 20.50
22时31分56秒 2 0.56 0.00 1.13 0.00 0.56 6.78 0.00 0.00 0.00 90.96
22时31分56秒 3 0.00 0.00 0.51 0.00 0.51 1.02 0.00 0.00 0.00 97.96
22时31分56秒 4 0.00 0.00 0.00 0.00 0.52 2.09 0.00 0.00 0.00 97.38
22时31分56秒 5 0.00 0.00 0.00 0.00 0.00 1.56 0.00 0.00 0.00 98.44
22时31分56秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
22时31分58秒 all 1.58 0.00 13.12 0.00 0.35 6.51 0.00 0.00 0.00 78.43
22时31分58秒 0 0.00 0.00 0.52 0.00 0.52 2.06 0.00 0.00 0.00 96.91
22时31分58秒 1 8.50 0.00 72.00 0.00 1.00 18.50 0.00 0.00 0.00 0.00
22时31分58秒 2 0.00 0.00 0.55 0.00 0.00 5.49 0.00 0.00 0.00 93.96
22时31分58秒 3 0.54 0.00 0.54 0.00 0.00 4.32 0.00 0.00 0.00 94.59
22时31分58秒 4 0.00 0.00 0.53 0.00 0.00 4.28 0.00 0.00 0.00 95.19
22时31分58秒 5 0.00 0.00 0.53 0.00 0.53 3.72 0.00 0.00 0.00 95.21
22时31分58秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
22时32分00秒 all 1.60 0.00 12.95 0.00 0.35 6.39 0.00 0.00 0.00 78.70
22时32分00秒 0 0.00 0.00 0.00 0.00 0.00 3.78 0.00 0.00 0.00 96.22
22时32分00秒 1 8.50 0.00 72.50 0.00 0.50 18.50 0.00 0.00 0.00 0.00
22时32分00秒 2 0.58 0.00 0.58 0.00 0.58 8.19 0.00 0.00 0.00 90.06
22时32分00秒 3 0.00 0.00 0.00 0.00 0.52 2.60 0.00 0.00 0.00 96.88
22时32分00秒 4 0.00 0.00 0.00 0.00 0.53 2.65 0.00 0.00 0.00 96.83
22时32分00秒 5 0.00 0.00 0.00 0.00 0.00 2.11 0.00 0.00 0.00 97.89
可以看到CPU 1
的空闲率(%idle)
为 0.00
, 其他的CPU 核心正常,即 httpd
应用 的 CPU时间分布 被固定到了 1 CPU
,httpd
服务即使业务高峰,也只能使用 CPU 1
,
.........
22时32分00秒 0 0.00 0.00 0.00 0.00 0.00 3.78 0.00 0.00 0.00 96.22
22时32分00秒 1 8.50 0.00 72.50 0.00 0.50 18.50 0.00 0.00 0.00 0.00
22时32分00秒 2 0.58 0.00 0.58 0.00 0.58 8.19 0.00 0.00 0.00 90.06
..........
代码语言:javascript复制96.22
0.00
90.06
如何恢复亲和性,只需要重起服务,脱离创建的Cgroup,或者把对应的 Cgroup 删除掉
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$systemctl restart httpd
cgroups-v2 CPU 带宽 测试
这里的带宽测试我们任然使用之前Demo,为了测试方便,在配置亲和性的基础上 观察带宽变化
配置 CPU 带宽测试
在 上面的控制组中 cpu.max
文件写入带宽配置,单位为微秒,
┌──[root@vms99.liruilongs.github.io]-[~]
└─$echo "200000 1000000" > /sys/fs/cgroup/Example/tasks/cpu.max
┌──[root@vms99.liruilongs.github.io]-[~]
└─$cat /sys/fs/cgroup/Example/tasks/cpu.max
200000 1000000
上面的配置即/sys/fs/cgroup/Example/tasks
子组中的所有进程在 1000000
微秒,也就是1 秒
内 可以使用CPU 的时间为200000
微秒,也就是 0.2 秒
。即每秒可以使用 CPU 的 20% 左右。
- 第一个值是允许的时间配额(以微秒为单位),用于子组中的所有进程可以在一段时间内运行。
- 第二个值指定时间段的长度。
需要注意的是,在一段时间内,当控制组中的进程共同耗尽此配额指定的时间时,它们会在该时间段的剩余时间内节流
,并且直到下一个时间段才允许运行
。
模拟业务高峰测试
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$ab -n 100000 -c 10000 127.0.0.1:80/
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
..................
Completed 90000 requests
apr_socket_recv: Connection reset by peer (104)
Total of 98379 requests completed
观察 CPU 1 的空闲率变化
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$ mpstat -P ALL 2
Linux 4.18.0-513.9.1.el8_9.x86_64 (vms99.liruilongs.github.io) 2024年05月15日 _x86_64_ (6 CPU)
22时07分13秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
22时07分15秒 all 0.00 0.00 0.08 0.00 0.00 0.00 0.00 0.00 0.00 99.92
22时07分15秒 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时07分15秒 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时07分15秒 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时07分15秒 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时07分15秒 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时07分15秒 5 0.00 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 99.50
22时07分15秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
22时07分17秒 all 0.34 0.00 3.83 0.00 0.26 2.39 0.00 0.00 0.00 93.19
22时07分17秒 0 0.00 0.00 1.07 0.00 0.53 4.28 0.00 0.00 0.00 94.12
22时07分17秒 1 2.00 0.00 20.50 0.00 0.50 6.50 0.00 0.00 0.00 70.50
22时07分17秒 2 0.00 0.00 0.53 0.00 0.53 3.74 0.00 0.00 0.00 95.19
22时07分17秒 3 0.00 0.00 0.50 0.00 0.00 0.00 0.00 0.00 0.00 99.50
22时07分17秒 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时07分17秒 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
22时07分17秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
22时07分19秒 all 0.42 0.00 3.04 0.00 0.08 1.94 0.00 0.00 0.00 94.51
22时07分19秒 0 0.00 0.00 0.00 0.00 0.00 2.03 0.00 0.00 0.00 97.97
22时07分19秒 1 2.49 0.00 17.91 0.00 0.00 5.47 0.00 0.00 0.00 74.13
22时07分19秒 2 0.00 0.00 0.00 0.00 0.00 0.50 0.00 0.00 0.00 99.50
22时07分19秒 3 0.00 0.00 0.00 0.00 0.00 1.02 0.00 0.00 0.00 98.98
22时07分19秒 4 0.00 0.00 0.00 0.00 0.00 1.03 0.00 0.00 0.00 98.97
22时07分19秒 5 0.00 0.00 0.00 0.00 0.51 1.53 0.00 0.00 0.00 97.96
可以看到,配置了带宽限制之后,即使业务高峰,CPU 1
的 空闲率也保持在 75%
左右,即有 25%
被使用
如何恢复带宽
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$echo max max | sudo tee /sys/fs/cgroup/Example/tasks/cpu.max
max max
┌──[root@vms99.liruilongs.github.io]-[~]
└─$cat /sys/fs/cgroup/Example/tasks/cpu.max
max 1000000
┌──[root@vms99.liruilongs.github.io]-[~]
└─$
cgroups-v2 CPU 权重 测试
这里为了Demo 演示,强制所有示例进程运行在单个 CPU 上。当在多个 CPU 上使用时,CPU 权重也会应用同样的原则。
未配置权重
创建两个 Cgroup 子组 tasks1
和 tasks2
,同时配置亲和性为 CPU 0
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$echo " cpu" >> /sys/fs/cgroup/cgroup.subtree_control
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$echo " cpuset" >> /sys/fs/cgroup/cgroup.subtree_control
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$mkdir /sys/fs/cgroup/Example/
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$echo " cpu" >> /sys/fs/cgroup/Example/cgroup.subtree_control
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$echo " cpuset" >> /sys/fs/cgroup/Example/cgroup.subtree_control
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$mkdir /sys/fs/cgroup/Example/tasks1/
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$echo "0" > /sys/fs/cgroup/Example/tasks1/cpuset.cpus
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$mkdir /sys/fs/cgroup/Example/tasks2/
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$echo "0" > /sys/fs/cgroup/Example/tasks2/cpuset.cpus
在 httpd 服务的基础上 添加 nginx 服务作为测试用例
确认当前亲和性
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep nginx | xargs -I {} taskset -p {}
pid 5001 的当前亲和力掩码:3f
pid 5002 的当前亲和力掩码:3f
。。。。。。。。。。。。。。。。。。。。。。。。。
pid 5007 的当前亲和力掩码:3f
┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep httpd | xargs -I {} taskset -p {}
pid 1362 的当前亲和力掩码:3f
pid 1479 的当前亲和力掩码:3f
pid 1483 的当前亲和力掩码:3f
pid 1484 的当前亲和力掩码:3f
pid 1487 的当前亲和力掩码:3f
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
pid 5585 的当前亲和力掩码:3f
pid 5586 的当前亲和力掩码:3f
pid 5587 的当前亲和力掩码:3f
pid 5588 的当前亲和力掩码:3f
┌──[root@vms99.liruilongs.github.io]-[~]
└─$
确认 Cgroup 控制组
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep httpd | xargs -I {} cat /proc/{}/cgroup
0::/system.slice/httpd.service
0::/system.slice/httpd.service
0::/system.slice/httpd.service
0::/system.slice/httpd.service
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
0::/system.slice/httpd.service
0::/system.slice/httpd.service
0::/system.slice/httpd.service
┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep nginx | xargs -I {} cat /proc/{}/cgroup
0::/system.slice/nginx.service
0::/system.slice/nginx.service
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
0::/system.slice/nginx.service
0::/system.slice/nginx.service
┌──[root@vms99.liruilongs.github.io]-[~]
└─$
把 ngixn
的所有进程添加到 tasks1
控制组
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$pgrep nginx | xargs -I {} echo {} > /sys/fs/cgroup/Example/tasks1/cgroup.procs
httpd
所有进程添加到 tasks2
控制组
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$pgrep httpd | xargs -I {} echo {} > /sys/fs/cgroup/Example/tasks2/cgroup.procs
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$
确认修改后的控制组
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep nginx | xargs -I {} cat /proc/{}/cgroup
0::/Example/tasks1
0::/Example/tasks1
。。。。。。。。。。。。。。。。。。。。。。。。。。
0::/Example/tasks1
┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep nginx | xargs -I {} cat /proc/{}/cgroup^C
┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep httpd | xargs -I {} cat /proc/{}/cgroup
0::/Example/tasks2
0::/Example/tasks2
0::/Example/tasks2
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
0::/Example/tasks2
0::/Example/tasks2
0::/Example/tasks2
确认修改后的亲和性
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep nginx | xargs -I {} taskset -p {}
pid 5001 的当前亲和力掩码:1
pid 5002 的当前亲和力掩码:1
。。。。。。。。。。。。。。。。。。。。。。。。。。。
pid 5007 的当前亲和力掩码:1
┌──[root@vms99.liruilongs.github.io]-[~]
└─$pgrep httpd | xargs -I {} taskset -p {}
pid 1362 的当前亲和力掩码:1
pid 1479 的当前亲和力掩码:1
pid 1483 的当前亲和力掩码:1
。。。。。。。。。。。。。。。。。。。。。。。
pid 5586 的当前亲和力掩码:1
pid 5587 的当前亲和力掩码:1
pid 5588 的当前亲和力掩码:1
┌──[root@vms99.liruilongs.github.io]-[~]
└─$
同时对两个 web 服务进行 业务量模拟
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$ab -n 10000000 -c 1000 127.0.0.1:80/
┌──[root@vms99.liruilongs.github.io]-[~]
└─$ab -n 10000000 -c 1000 127.0.0.1:8080/
top 命令观察 CPU 变化,这里主要观察 %CPU
, CPU 利用率,可以发现 ,由于配置了 亲和性,所以负载集中在 Cpu0
, 且通过 load average: 39.21
可以看到当前 CPU 处于 饱和状态。
top - 21:18:18 up 2:02, 4 users, load average: 39.21, 15.90, 7.38
Tasks: 280 total, 6 running, 274 sleeping, 0 stopped, 0 zombie
%Cpu0 : 11.8/88.2 100[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||]
%Cpu1 : 0.4/9.7 10[|||||| ]
%Cpu2 : 0.4/8.6 9[||||| ]
%Cpu3 : 1.1/18.8 20[||||||||||||| ]
%Cpu4 : 1.5/15.6 17[||||||||||| ]
%Cpu5 : 1.1/13.6 15[|||||||||| ]
MiB Mem : 6141.5 total, 2869.9 free, 895.4 used, 2376.2 buff/cache
MiB Swap: 2068.0 total, 2068.0 free, 0.0 used. 4979.0 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND
6227 root 20 0 362016 138624 5224 R 49.2 2.2 0:52.90 ab
6228 root 20 0 362016 40292 5020 S 13.6 0.6 0:13.98 ab
5002 nginx 20 0 124896 9220 6424 R 7.0 0.1 5:09.56 nginx
5004 nginx 20 0 124896 9220 6424 S 6.6 0.1 0:35.25 nginx
5005 nginx 20 0 124896 9220 6424 S 6.6 0.1 0:34.57 nginx
5007 nginx 20 0 124896 9220 6424 R 6.6 0.1 0:50.00 nginx
5006 nginx 20 0 124896 9220 6424 S 6.3 0.1 0:38.23 nginx
5003 nginx 20 0 124896 9220 6424 R 6.0 0.1 0:38.15 nginx
5584 apache 20 0 2500284 20940 7260 S 3.0 0.3 0:02.56 httpd
1484 apache 20 0 2565820 22080 7172 S 2.7 0.4 0:05.37 httpd
1487 apache 20 0 2500284 20748 7172 S 2.7 0.3 0:05.39 httpd
5321 apache 20 0 2500284 24232 7260 S 2.7 0.4 0:02.78 httpd
5585 apache 20 0 2500284 21228 7196 S 2.7 0.3 0:02.54 httpd
5588 apache 20 0 2500284 18168 7172 S 2.7 0.3 0:02.53 httpd
1483 apache 20 0 2696956 27596 7172 S 2.3 0.4 0:05.44 httpd
5047 apache 20 0 2565820 25044 7196 S 2.3 0.4 0:03.62 httpd
5122 apache 20 0 2500284 20552 7196 S 2.3 0.3 0:03.46 httpd
5188 apache 20 0 2500284 21472 7260 S 2.3 0.3 0:03.05 httpd
5189 apache 20 0 2500284 22068 7196 S 2.3 0.4 0:03.04 httpd
5320 apache 20 0 2500284 22832 7196 S 2.3 0.4 0:02.82 httpd
5322 apache 20 0 2565820 21572 7196 S 2.3 0.3 0:02.66 httpd
5323 apache 20 0 2500284 21180 7196 S 2.3 0.3 0:02.70 httpd
可以发现,如果权重不设置各占 50%,即如果子 cgroup 有多个正在运行的进程,则分配给相应 cgroup 的 CPU 时间将平均分配给该 cgroup 的成员进程
。
配置CPU权重测试
这里我们给 tasks1
控制组,也就是 nginx
的配置权重为 10
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$echo "10" > /sys/fs/cgroup/Example/tasks1/cpu.weight
给 task2
控制组,也就是 httpd
控制组 配置权重为 90
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$echo "90" > /sys/fs/cgroup/Example/tasks2/cpu.weight
┌──[root@vms99.liruilongs.github.io]-[/sys/fs/cgroup]
└─$
对两个服务同时进行业务量模拟
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$ab -n 10000000 -c 1000 127.0.0.1:80/
┌──[root@vms99.liruilongs.github.io]-[~]
└─$ab -n 10000000 -c 1000 127.0.0.1:8080/
top
命令观察CPU0 利用率 变化 ,71.5(nginx)
, 9(nginx)
,权重对应于每个应用程序分配的 CPU 时间的大约
nginx: 10%
httpd: 90%
top - 21:29:14 up 2:13, 4 users, load average: 11.42, 5.08, 5.37
Tasks: 279 total, 9 running, 270 sleeping, 0 stopped, 0 zombie
%Cpu0 : 13.2/86.8 100[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||]
%Cpu1 : 0.0/7.4 7[||||| ]
%Cpu2 : 0.4/7.8 8[||||| ]
%Cpu3 : 0.7/5.6 6[|||| ]
%Cpu4 : 0.3/4.5 5[||| ]
%Cpu5 : 0.4/7.8 8[||||| ]
MiB Mem : 6141.5 total, 2299.4 free, 773.0 used, 3069.1 buff/cache
MiB Swap: 2068.0 total, 2068.0 free, 0.0 used. 5100.5 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND
6409 root 20 0 362016 27736 5020 S 27.3 0.4 0:04.96 ab
6408 root 20 0 362016 26376 5184 R 11.3 0.4 0:02.79 ab
5588 apache 20 0 2500284 19988 7172 S 5.0 0.3 0:03.69 httpd
1484 apache 20 0 2565820 22380 7172 S 4.7 0.4 0:06.52 httpd
1487 apache 20 0 2500284 19504 7172 S 4.7 0.3 0:06.54 httpd
5047 apache 20 0 2565820 24736 7196 S 4.7 0.4 0:04.81 httpd
5584 apache 20 0 2500284 21788 7260 S 4.7 0.3 0:03.73 httpd
5585 apache 20 0 2500284 20644 7196 S 4.7 0.3 0:03.72 httpd
1483 apache 20 0 2696956 28484 7172 S 4.3 0.5 0:06.64 httpd
5122 apache 20 0 2500284 21264 7196 S 4.3 0.3 0:04.62 httpd
5188 apache 20 0 2500284 21952 7260 S 4.3 0.3 0:04.22 httpd
5189 apache 20 0 2500284 22248 7196 S 4.3 0.4 0:04.20 httpd
5320 apache 20 0 2500284 22376 7196 S 4.3 0.4 0:04.00 httpd
5321 apache 20 0 2500284 22832 7260 S 4.3 0.4 0:03.94 httpd
5322 apache 20 0 2565820 20444 7196 S 4.3 0.3 0:03.81 httpd
5323 apache 20 0 2500284 19432 7196 S 4.3 0.3 0:03.85 httpd
5586 apache 20 0 2500284 19348 7196 S 4.3 0.3 0:03.62 httpd
5587 apache 20 0 2500284 19908 7236 S 4.3 0.3 0:03.68 httpd
5002 nginx 20 0 124896 9220 6424 R 1.7 0.1 5:26.73 nginx
5005 nginx 20 0 124896 9220 6424 R 1.7 0.1 0:51.50 nginx
5007 nginx 20 0 124896 9220 6424 R 1.7 0.1 1:07.06 nginx
5003 nginx 20 0 124896 9220 6424 R 1.3 0.1 0:55.37 nginx
5004 nginx 20 0 124896 9220 6424 R 1.3 0.1 0:52.33 nginx
5006 nginx 20 0 124896 9220 6424 R 1.3 0.1 0:55.32 nginx
Systemd 配置 亲和性,权重,带宽
上面的配置方式直接通过把 服务的所有进程添加到 Cgroup,实际上可以通过 直接通过 服务来限制
在由 systemd 管理的系统上,每个系统服务在其 cgroup 中启动。通过启用对 CPU cgroup 控制器的支持,系统使用对 CPU 资源的服务感知分布,而不是按进程分布
。在服务感知型分发
中,每个服务收到的 CPU 时间与系统上运行的所有其他服务的 CPU 时间大致相同,无论组成该服务的进程数量如何。
如果特定的服务需要更多 CPU 资源,您可以通过更改该服务的 CPU 时间分配策略
来授予它们。
配置流程
代码语言:javascript复制# 检查
systemctl show --property <CPU time allocation policy option> <service name>
# 配置
systemctl set-property <service name> <CPU time allocation policy option>=<value>
# 验证
systemctl show --property <CPU time allocation policy option> <service name>
配置选项可以通过 systemd.resource-control
帮助文档获取
┌──[root@vms99.liruilongs.github.io]-[~]
└─$man systemd.resource-control
................
OPTIONS
Units of the types listed above can have settings for resource control configuration:
CPUAccounting=
Turn on CPU usage accounting for this unit. Takes a boolean argument. Note that turning
on CPU accounting for one unit will also implicitly turn it on for all units contained in
the same slice and for all its parent slices and the units contained therein. The system
default for this setting may be controlled with DefaultCPUAccounting= in systemd-
system.conf(5).
CPUWeight=weight, StartupCPUWeight=weight
Assign the specified CPU time weight to the processes executed, if the unified control
group hierarchy is used on the system. These options take an integer value and control
the "cpu.weight" control group attribute. The allowed range is 1 to 10000. Defaults to
100. For details about this control group attribute, see cgroup-v2.txt[2] and
sched-design-CFS.txt[4]. The available CPU time is split up among all units within one
slice relative to their CPU time weight.
While StartupCPUWeight= only applies to the startup phase of the system, CPUWeight=
applies to normal runtime of the system, and if the former is not set also to the startup
phase. Using StartupCPUWeight= allows prioritizing specific services at boot-up
differently than during normal runtime.
Implies "CPUAccounting=true".
These settings replace CPUShares= and StartupCPUShares=.
CPUQuota=
Assign the specified CPU time quota to the processes executed. Takes a percentage value,
suffixed with "%". The percentage specifies how much CPU time the unit shall get at
maximum, relative to the total CPU time available on one CPU. Use values > 100% for
allotting CPU time on more than one CPU. This controls the "cpu.max" attribute on the
unified control group hierarchy and "cpu.cfs_quota_us" on legacy. For details about these
control group attributes, see cgroup-v2.txt[2] and sched-design-CFS.txt[4].
Example: CPUQuota=20% ensures that the executed processes will never get more than 20%
CPU time on one CPU.
Implies "CPUAccounting=true".
AllowedCPUs=
Restrict processes to be executed on specific CPUs. Takes a list of CPU indices or ranges
Manual page systemd.resource-control(5) line 63 (press h for help or q to quit).
.............................
CPUWeight 配置
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$systemctl show --property CPUWeight httpd.service
CPUWeight=[not set]
┌──[root@vms99.liruilongs.github.io]-[~]
└─$systemctl set-property httpd.service CPUWeight=200
┌──[root@vms99.liruilongs.github.io]-[~]
└─$systemctl show --property CPUWeight httpd.service
CPUWeight=200
CPUQuota 配置
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$systemctl set-property httpd.service CPUQuota=20%
┌──[root@vms99.liruilongs.github.io]-[~]
└─$systemctl show --property CPUQuota httpd.service
亲和性配置
代码语言:javascript复制┌──[root@vms99.liruilongs.github.io]-[~]
└─$systemctl show --property AllowedCPUs httpd.service
AllowedCPUs=
┌──[root@vms99.liruilongs.github.io]-[~]
└─$systemctl set-property httpd.service AllowedCPUs=1-3
┌──[root@vms99.liruilongs.github.io]-[~]
└─$systemctl show --property AllowedCPUs httpd.service
AllowedCPUs=1-3
博文部分内容参考
© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知 :)
https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/8/html/managing_monitoring_and_updating_the_kernel/
© 2018-2024 liruilonger@gmail.com, All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)