Linux cgroups v2 CPU 配额和权重怎么区分
来源:17golang原创
时间:2026-09-08 04:29:26 380浏览 收藏
Linux cgroups v2 里,cpu.weight 和 cpu.max 不是两种写法的同一个参数:前者解决“多个活跃子组如何分 CPU”,后者解决“这个组在一个周期内最多能用多少 CPU 时间”。如果只想让后台任务在竞争时少拿一些资源,用权重;如果必须把计算量压在明确上限内,用配额,必要时两者叠加。
cpu.weight默认值为 100,范围是 1–10000,含义是同级活跃子 cgroup 的相对份额,不是百分比。cpu.max使用$MAX $PERIOD,例如50000 100000表示每 100000 微秒最多使用 50000 微秒。memory.max是硬限制,memory.high更像回收压力与节流边界;委派子树始终不能突破父级限制。
先把 cpu.weight 和 cpu.max 放回两种模型
可以把同一父级下的两个活跃子 cgroup 想成共同争用一块 CPU 资源。cpu.weight=200 的组和 cpu.weight=100 的组,在都需要 CPU 时大致按 2:1 分配;其中一组空闲时,另一组可以利用空出来的时间,所以权重是“有竞争时的倾向”,不会自动切出固定百分比。
cpu.max 则给出带宽上限。格式是 $MAX $PERIOD,例如下面的设置把一个工作组限制在半个周期:
# 创建实验组;实际环境应确认 /sys/fs/cgroup 已挂载为 cgroup v2 sudo mkdir -p /sys/fs/cgroup/demo-worker # 让父级负责向子组分配 CPU 与内存控制器 echo "+cpu +memory" | sudo tee /sys/fs/cgroup/subtree_control # 每 100000 微秒最多使用 50000 微秒 CPU 时间 echo "50000 100000" | sudo tee /sys/fs/cgroup/demo-worker/cpu.max # 只有发生 CPU 竞争时才体现相对优先级 echo 200 | sudo tee /sys/fs/cgroup/demo-worker/cpu.weight

因此,“给低优先级任务设置 20% CPU”并不严谨:若要表达硬上限,应使用 cpu.max;若只是希望它在和别的任务竞争时少分一些,应使用 cpu.weight。配额触发后,cpu.stat 中的 nr_throttled 和 throttled_usec 才能说明确实发生了限流。
用一个 worker.slice 组合配额、权重和内存
把进程写入 cgroup.procs 后,CPU 和内存规则才会作用到它。下面的片段展示最小组合;生产环境不要直接改系统服务所在的层级,最好为业务预留独立的父级。
# 设置 512 MiB 硬内存上限;超出且无法回收时可能触发该组内的 OOM 处理
echo "512M" | sudo tee /sys/fs/cgroup/demo-worker/memory.max
# 观察到高水位后施加回收压力,但它不是 memory.max 那样的硬上限
echo "384M" | sudo tee /sys/fs/cgroup/demo-worker/memory.high
# 将目标进程 PID 放入 cgroup;PID 应替换成实际业务进程号
echo "${PID}" | sudo tee /sys/fs/cgroup/demo-worker/cgroup.procs
这个组合表达的是:CPU 方面先受 cpu.max 的绝对上限约束,再在同级竞争中参考 cpu.weight;内存方面优先用 memory.high 观察回收压力,确有硬边界需求时再设置 memory.max。不要把 CPU 配额的百分比直接套到内存上,两个控制器的单位和失效方式不同。
cgroups v2 的内存与委派边界
memory.max 是主要硬限制,无法继续回收时会在该 cgroup 范围内触发 OOM 处理;memory.high 是节流和回收压力边界,超过它不等于立即杀进程。排查内存问题时,先读 memory.current、memory.events,再决定是回收压力过高还是硬上限确实过小。
委派也有一个容易忽略的边界:低权限用户可以在被委派的子树里创建子 cgroup、组织自己的进程,但不能修改控制父级资源分配的文件,更不能通过子树逃出上层的 CPU 或内存限制。cgroup.procs 和 cgroup.subtree_control 是组织子树的重要入口,权限应单独授予,不要把整个目录粗暴地改成可写。

发现配置了却不生效时怎么判断
先确认控制器是否在正确层级启用,再确认进程位置,最后看统计项,不要只看写入命令是否返回成功:
# 查看当前层级可用的控制器和已经启用的子树控制器 cat /sys/fs/cgroup/cgroup.controllers cat /sys/fs/cgroup/cgroup.subtree_control # 确认进程确实属于目标组 cat /sys/fs/cgroup/demo-worker/cgroup.procs # 观察 CPU 是否真的被限流,以及内存是否触发事件 cat /sys/fs/cgroup/demo-worker/cpu.stat cat /sys/fs/cgroup/demo-worker/memory.events
常见误区有三个:把 cpu.weight 当成固定百分比;只设置了父级文件却没有把进程放入子组;把 memory.high 当成绝对内存上限。最后可以用下面的速查表做选择。
| 目标 | 优先设置 | 判断信号 |
|---|---|---|
| 竞争时让某组多分或少分 CPU | cpu.weight | 同级活跃组的相对份额 |
| 限制每个周期的 CPU 用量 | cpu.max | nr_throttled、throttled_usec |
| 设置内存硬边界 | memory.max | memory.events 与 OOM 事件 |
| 提前施加回收压力 | memory.high | 回收、节流和业务延迟变化 |
相关问题
cpu.weight=100 是否就是 100% CPU?
不是。100 是默认权重值,只在同一父级下与其他活跃子组比较。需要固定上限时使用 cpu.max。
为什么写入 cpu.max 后进程仍能短时间突发?
配额按周期统计,短时观察可能跨越周期边界;应结合 cpu.stat 的限流计数和持续时间判断,而不是用一次瞬时 CPU 百分比下结论。
更完整的接口语义和委派规则可参考 Linux 内核 Control Group v2 文档。在生产环境调整前,先确认发行版的 systemd 或容器运行时是否也在管理同一层级。
-
426 收藏
-
387 收藏
-
242 收藏
-
238 收藏
-
402 收藏
-
105 收藏
-
171 收藏
-
387 收藏
-
147 收藏
-
158 收藏
-
322 收藏
-
196 收藏
-
118 收藏
-
384 收藏
-
150 收藏
-
302 收藏
-
468 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习