cgroup v2 是当前 Linux CPU 资源隔离的唯一推荐路径,cgroup v1 的 cpu 和 cpuacct 子系统已不建议新项目使用,且在较新内核(5.15+)中默认禁用;根本原因在于未启用 cgroup v2 统一层级或内核参数缺失 systemd.unified_cgroup_hierarchy=1,导致 cpu.weight、cpu.max 等配置被静默忽略。

直接说结论:cgroup v2 是当前 Linux CPU 资源隔离的唯一推荐路径,cgroup v1 的 cpu 和 cpuacct 子系统已不建议新项目使用,且在较新内核(5.15+)中默认禁用。
为什么 systemd 创建的 .slice 有时不生效?
根本原因是未启用 cgroup v2 统一层级,或内核启动参数中缺失 systemd.unified_cgroup_hierarchy=1。即使 systemd 版本 ≥ 243,若内核未启用 v2,cpu.weight、cpu.max 等配置会被静默忽略。
- 检查是否启用 v2:
cat /proc/filesystems | grep cgroup
—— 应只看到cgroup2,无cgroup(v1) - 验证当前 hierarchy:
mount | grep cgroup
—— 输出应含type cgroup2且挂载点为/sys/fs/cgroup - 若未启用:编辑
/etc/default/grub,在GRUB_CMDLINE_LINUX中追加systemd.unified_cgroup_hierarchy=1,再运行sudo update-grub && sudo reboot
cpu.max 和 cpu.weight 的实际行为差异
cpu.weight 是相对权重(1–10000),仅在多个 cgroup 同时争抢 CPU 时起作用;cpu.max 是硬性配额(如 50000 100000 表示最多用 50% CPU 时间),无视其他 cgroup 是否空闲。
-
cpu.weight=100和cpu.weight=1000在只有自己运行时效果完全一样 -
cpu.max=10000 100000表示每 100ms 周期最多运行 10ms,超时即被 throttled(可通过cat cpu.stat查看nr_throttled) - 设置
cpu.max后,cpu.weight不再参与调度决策——两者互斥使用场景 - 注意单位:第二字段是 period(默认 100000μs),第一字段是 quota;设为
max表示不限制
用 systemd-run 快速测试 CPU 隔离是否生效
避免手动写 /sys/fs/cgroup/ 路径,用 systemd 接口更可靠,也自动处理生命周期。
- 限制某进程最多用 30% CPU:
systemd-run --scope -p CPUWeight=10 --scope sleep 300
- 等价于硬配额方式(更严格):
systemd-run --scope -p CPUQuota=30% --scope sleep 300
- 验证是否生效:
systemd-cgtop -P
或cat /sys/fs/cgroup/
$(systemd-run --scope --pipe true)/cpu.stat | grep throttled - 常见陷阱:如果目标进程是多线程,且未绑定到特定 cgroup,线程可能逃逸到 root cgroup——务必用
--scope包裹整个命令,而非仅启动器
真正容易被忽略的是:CPU 隔离效果高度依赖负载类型。对大量 syscalls 或锁竞争型程序,cpu.max 可能导致显著延迟尖刺,而不仅仅是吞吐下降;监控时不能只看 cpu.usage,必须结合 cpu.stat 中的 nr_throttled 和 throttled_time 才算看清真相。










