CPU 配额(cpu.cfs_quota_us)与周期(cpu.cfs_period_us)的配置机制
在 Linux CFS(Completely Fair Scheduler)调度器下,容器运行时通过 cpu.cfs_quota_us 和 cpu.cfs_period_us 两个 cgroup 参数共同定义 CPU 资源配额。理解这两个参数的配置机制,是定位 CPU 配额竞争瓶颈的前提。
3.1 核心参数定义
| 参数 | 单位 | 默认值 | 含义 |
|---|---|---|---|
cpu.cfs_period_us |
微秒(µs) | 100000(100ms) | 一个调度周期的时间窗口长度 |
cpu.cfs_quota_us |
微秒(µs) | -1(无限制) | 在一个周期内,该 cgroup 中所有进程可使用的最大 CPU 时间 |
cpu.stat |
— | — | 记录调度延迟(nr_periods, nr_throttled, throttled_time) |
关键理解:配额与周期的比值决定了容器可获得的 CPU 核心数上限。例如
quota=200000、period=100000 表示容器最多可使用 2 个完整 CPU 核心。
3.2 配额计算与 CPU 核心数映射
容器可获得的 CPU 核心数上限计算公式为:
CPU 核心数上限 = cpu.cfs_quota_us / cpu.cfs_period_us
常见配置示例:
- 1 核限制:
quota=100000,period=100000→ 比值 = 1.0 - 2 核限制:
quota=200000,period=100000→ 比值 = 2.0 - 0.5 核限制:
quota=50000,period=100000→ 比值 = 0.5 - 无限制:
quota=-1→ 不进行配额限制,可抢占宿主机所有空闲 CPU
常见误区:配额比值不是硬保留,而是上限。即使配置了 2 核,若宿主机空闲,容器仍可能被限制在 2 核以内;若宿主机繁忙,容器可能无法达到 2 核。
3.3 调度周期与配额耗尽机制
CFS 调度器在每个周期开始时重置配额计数器。若容器内进程在该周期内消耗的 CPU 时间达到 quota 值,则会被 throttled(节流),直到下一个周期开始才能继续运行。
3.4 多核场景下的配额分配
当配额比值大于 1 时,容器可以在一个周期内同时使用多个 CPU 核心。CFS 调度器会将配额时间分配到各个核心上,但总消耗不超过 quota。
| 配额比值 | 理论最大核心数 | 调度行为 |
|---|---|---|
| 0.5 | 0.5 核 | 每 100ms 周期内最多运行 50ms,无论使用几个核心 |
| 1.0 | 1 核 | 可在一个核心上运行 100ms,或两个核心各运行 50ms |
| 2.0 | 2 核 | 可在两个核心上各运行 100ms,或四个核心各运行 50ms |
| 4.0 | 4 核 | 可在四个核心上各运行 100ms,或八个核心各运行 50ms |
性能调优要点:当容器内存在大量短线程并发时,即使配额比值足够,也可能因为线程切换开销导致实际吞吐量低于预期。此时应检查
/sys/fs/cgroup/cpu/cpu.stat 中的 nr_throttled 是否持续增长。
3.5 配置生效与验证
在容器运行时(如 Docker、containerd)中,CPU 配额通常通过命令行参数或 Kubernetes resource limits 进行配置:
# Docker 示例:限制容器使用 1.5 核
docker run --cpus=1.5 --name my_container nginx
# 等效 cgroup 配置
echo 150000 > /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_quota_us
echo 100000 > /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_period_us
# 验证当前配置
cat /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_quota_us
cat /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_period_us
# 查看节流统计
cat /sys/fs/cgroup/cpu/docker/<container_id>/cpu.stat
# 输出示例:
# nr_periods 1000
# nr_throttled 45
# throttled_time 23456789
3.6 配置陷阱与最佳实践
- 周期过短(< 10ms):增加调度器开销,可能导致频繁节流,适合延迟敏感型业务。
- 周期过长(> 1s):配额耗尽后等待时间过长,导致容器响应延迟飙升。
- 配额设置过小:即使宿主机 CPU 空闲,容器也无法利用,造成资源浪费。
- 配额设置过大:容器可能抢占过多 CPU,影响同节点其他容器。
- 推荐实践:保持
period=100000(100ms),根据业务负载调整quota,并通过cpu.stat监控节流比例。
排查命令速查:使用
cat /sys/fs/cgroup/cpu/cpu.stat | grep throttled 快速判断容器是否遭遇 CPU 配额竞争。若 nr_throttled 持续增长且 throttled_time 占比超过 5%,说明配额不足或周期配置不合理。