首页/系统/Linux 内核与性能调优速查/cgroup v2 cpu.stat 节流诊断
CPU 与调度60 条

cgroup v2 cpu.stat 节流诊断

cpu.stat 提供 usage_usec、nr_periods、nr_throttled、throttled_usec 等计数;nr_throttled 增长说明任务反复撞上 cpu.max 限额。

文件是什么

cgroup v2 的 cpu.stat 记录某个控制组消耗的 CPU 时间计数,以及受 CPU 限额约束的统计数据,是判断「容器是不是被限额卡住」的一手证据。它包含 usage_usec(累计 CPU 时间)、user_usec/system_usec(用户态与内核态拆分)、nr_periods、nr_throttled、throttled_usec;后三个字段只在设置了 cpu.max 之后才有意义,nr_throttled 与 throttled_usec 增长说明任务反复撞上限额并被强制等待。

基本信息

路径/sys/fs/cgroup/<组路径>/cpu.stat(cgroup v2 unified)
单位微秒(usec);计数为累计值
限额接口cpu.max,格式「quota period」,如 200000 100000 表示 2 核
systemd 对应CPUQuota=(限额)、CPUWeight=(权重)
cgroup v1 差异位于 /sys/fs/cgroup/cpu/<组>/,限额用 cpu.cfs_quota_us / cpu.cfs_period_us
权限读取一般可读;修改需 root 或委派写权限

典型使用场景

  • 容器出现周期性延迟尖刺:throttled_usec 持续增长即为节流导致,需放宽 CPUQuota
  • 上线前压测:对比设置限额与不设限额时的吞吐,量化节流代价
  • 混部环境排查「谁在拖慢谁」:逐个 slice 看 nr_throttled 占比
  • 确认限额是否过大闲置:usage_usec 长期远低于配额说明配额虚高
  • 与 cpu.pressure(PSI)联合使用,区分限额节流与宿主侧排队

查看与调整

查看与调整
cat /sys/fs/cgroup/myapp.slice/cpu.max  # 查看限额:如 200000 100000 表示 2 核
cat /sys/fs/cgroup/myapp.slice/cpu.stat  # 读取全部计数器
awk '$1=="throttled_usec"{print $2}' /sys/fs/cgroup/myapp.slice/cpu.stat  # 只看累计节流时间
sleep 60  # 等一分钟后再读一次,两次相减才是当前每秒的节流增量
systemctl set-property myapp.service CPUQuota=200%  # 临时放宽到 2 核,立即生效
systemctl show myapp.service -p CPUQuotaPerSecUSec  # 核对系统最终生效的限额值

字段逐项读法

字段含义判读要点
usage_usec该组累计消耗的 CPU 时间除以墙钟时间可换算成平均核数
user_usec / system_usec用户态与内核态时间拆分system 占比高要查系统调用或内核处理
nr_periods限额周期总数分母,用于算节流比例
nr_throttled被节流的周期数与 nr_periods 的比值接近 1 表示长期贴限额
throttled_usec被强制等待的累计时间要看增量,绝对值不代表当前状态
nr_throttled 与 throttled_usec 都是累计值,单次读取的绝对值说明不了「现在是否还在被节流」。标准做法是间隔采样两次求差值;服务重启后计数归零,跨重启比较需要外部指标系统。
宿主 vCPU 超卖、NUMA 争抢或邻居占用导致的排队不会记入本组的 throttled_usec。这类场景要看宿主机 steal time、cpu.pressure 或宿主侧调度指标,避免把超卖问题误判为容器限额问题。

易错点

  • 只看 usage_usec 判断「限额没用满」:被节流的组明明想要更多 CPU 却拿不到,必须看 throttled_usec 和 nr_throttled
  • 拿累计值直接下结论,不做两次采样差分,把历史节流当成当前故障
  • 照抄 cgroup v1 的路径与字段名(cpu.cfs_quota_us、/sys/fs/cgroup/cpu/),在 v2 系统上读不到数据或读错文件
  • 只在 systemd 侧放宽 CPUQuota,而容器编排层(k8s limits、cpu cfs quota)另有上限或按核 pin,实际额度没变
  • 用 CPUWeight 代替 CPUQuota 解决问题:权重只在竞争时按比例分配,不提供硬上限,也不产生 nr_throttled 计数,故障模型完全不同

数据来源与参考

  • Linux 内核 Documentation/admin-guide/cgroup-v2.rst
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌