cgroups测试cpu bug
您遇到的 cgroup CPU 份额控制效果不明显 的问题,核心原因在于对 Linux 完全公平调度器 (CFS) 机制的理解偏差及实践场景的特殊性。以下是详细分析和解决方案:
一、关键认知纠偏
❌ 常见误解:“shares=200 vs 800 → 严格 20%:80% 硬性保障”
✅ 真实规则:
cpu.shares
定义的是 相对优先级权重,而非绝对资源配额。- 当单一 cgroup 内有多个进程时,shares 决定它们之间的资源争夺比例;
- 若整组仅一个进程,该进程可获得所在层级的全部可用 CPU 时间片(不受 shares 数值限制)。
👉 因此您的测试场景中:
lesscpu
组的md5sum
和morecpu
组的sha1sum
各自独占自己所在层的全额 CPU 资源,二者本质上处于平等竞争地位!
二、实验设计缺陷拆解
环节 | 现存问题 | 影响程度 |
---|---|---|
并发模型 | 单进程/单组 → 无组内竞争 | ⭐⭐⭐⭐⭐ 导致 shares 失效 |
观测工具 | top 仅反映瞬时采样 | ⭐⭐⭐ 无法捕捉长期统计规律 |
负载特性 | 密码学计算非满负荷 | ⭐⭐ 未触发真正的 CPU 争抢 |
环境干扰 | 未隔离其他系统进程 | ⭐⭐⭐⭐ 后台进程稀释效果 |
三、科学验证方案 & 预期现象
🔧 修正版测试步骤
# 创建两组并设置份额
mkdir -p /sys/fs/cgroup/cpu/group1
echo 200 > /sys/fs/cgroup/cpu/group1/cpu.shares
mkdir -p /sys/fs/cgroup/cpu/group2
echo 800 > /sys/fs/cgroup/cpu/group2/cpu.shares# 同时启动两个高负载进程(强制持续竞争)
cgexec -g cpu:group1 yes > /dev/null & # PID_A
cgexec -g cpu:group2 yes > /dev/null & # PID_B
📊 正确观测方式
工具 | 用法 | 预期结果 |
---|---|---|
ps -o comm,pid,psr,ni -C 'yes' | 实时查看进程亲和性+优先级 | PID_B 的 ni 值应为 PID_A 的 4 倍 |
pidstat -u -h <PID_A> <PID_B> 1 | 每秒输出两进程的 CPU 占比 | 长期统计下 B : A ≈ 4:1 |
cat /proc/<PID>/schedstat | 查看调度器原始数据 | policy 字段显示 CFS |
📌 关键原理说明
- 只有当同一层级存在多个活跃进程时,CFS 才会依据 shares 进行动态调谐。
yes
命令通过死循环制造持续满负荷,迫使调度器频繁介入分配。pidstat
的统计周期越长(如观察 60 秒),结果越趋近理论比例。
四、为何原始测试无效?
-
伪并行假象:
- 您先后执行两条独立命令,实质是串行操作而非真正并发。
md5sum /dev/zero
虽看似永续,实则单线程纯计算无阻塞,不会主动释放 CPU。
-
top 命令局限性:
- 默认 3 秒刷新间隔 + 仅显示当前时刻快照 → 易受进程调度时机影响。
- 缺乏历史累计数据支撑,难以发现微小差异。
-
算法轻量化:
- MD5/SHA1 属于轻量级加密算法,现代 CPU 可在很少时钟周期内完成单次运算。
- 真实负载远低于 CPU 最大吞吐量,无法暴露调度器干预效果。
五、进阶验证建议
🚀 强化竞争压力测试
# 在每组启动多个同名进程加剧竞争
for i in {1..5}; do cgexec -g cpu:group1 sleep 100 & done
for i in {1..5}; do cgexec -g cpu:group2 sleep 100 & done
👉 此模式下,组内 5 个进程将严格按照 200:800 的比例分享 CPU 时间片。
🛠️ 可视化监控方案
# 安装图形化监控工具
yum install gnuplot htop -y# 持续记录 CPU 使用率
while true; do ps -o %cpu,comm -C 'yes' | grep -v PID | awk '{print strftime("%H:%M:%S") "\t" $1}' >> data.log; sleep 1;
done# 生成趋势图
gnuplot <<EOF
set title "CPU Allocation Over Time"
set xlabel "Time"
set ylabel "CPU %"
plot "data.log" using 1:2 with lines title "Group1", \"data.log" using 1:3 with lines title "Group2"
EOF
六、结论与最佳实践
场景 | 推荐方案 | 备注 |
---|---|---|
开发调试 | 使用 stress-ng --cpu 2 生成可控负载 | 精准模拟 CPU 压力 |
生产环境 | 结合 nice/ionice 调整优先级 | 配合 cgroup 实现三级管控 |
监控取证 | perf record -ag + perf report | 获取调度器事件明细 |
核心原则:
CPU shares 只在 组内多进程共存 时生效,其本质是 相对权重而非绝对配额。若要实现严格资源隔离,需改用
quota
或转向更新的 cgroup v2 + controllers 体系。