1. 课程导论:CFS 调度器概述、cgroup v1 与 v2 对比、容器化环境中的 CPU 资源隔离挑战
1.1 CFS 调度器概述
完全公平调度器(Completely Fair Scheduler, CFS)是 Linux 内核默认的 CPU 调度器,自 2.6.23 版本引入。其核心设计理念是:为每个可运行的线程分配一个“虚拟运行时间”(vruntime),调度器始终选择 vruntime 最小的线程来执行,从而在宏观上实现所有线程对 CPU 时间的公平共享。
CFS 摒弃了传统的时间片轮转模型,采用基于红黑树(Red-Black Tree)的调度队列。每个就绪线程的 vruntime 作为红黑树的键值,调度操作即从树的最左节点取出最小 vruntime 的线程。
关键指标: CFS 通过
sched_latency_ns(调度延迟)、min_granularity_ns(最小粒度)和 targeted_preemption_latency(目标抢占延迟)三个参数控制调度行为。默认调度延迟为 6ms,最小粒度为 0.75ms。
1.2 cgroup v1 与 v2 对比
cgroup(Control Groups)是 Linux 内核提供的资源隔离机制。在容器化环境中,cgroup 用于限制、统计和隔离进程组的 CPU 使用。cgroup v1 和 v2 在 CPU 子系统的设计上有显著差异。
| 对比维度 | cgroup v1 | cgroup v2 |
|---|---|---|
| 层次结构 | 多层级树,每个子系统独立挂载 | 统一层级树,所有子系统共用一个挂载点 |
| CPU 控制器 | cpu 和 cpuacct 分离 |
cpu 控制器统一管理调度和统计 |
| 权重配置 | cpu.shares(相对权重) |
cpu.weight(归一化权重,范围 1-10000) |
| 带宽限制 | cpu.cfs_quota_us + cpu.cfs_period_us |
cpu.max(格式:quota period) |
| CPU 亲和性 | cpuset.cpus(独立 cpuset 子系统) |
cpuset.cpus(集成在统一层级) |
| 压力通知 | 不支持 | cpu.pressure 提供 PSI 指标 |
| 线程级控制 | 仅支持进程级 | 支持线程级(threaded mode) |
迁移建议: 主流容器运行时(Docker 20.10+、containerd 1.5+)已默认使用 cgroup v2。如果仍在使用 cgroup v1,建议规划迁移,以获得更一致的资源视图和更丰富的监控能力。
1.3 容器化环境中的 CPU 资源隔离挑战
在容器化环境中,多个容器共享同一宿主机内核,CPU 资源隔离面临以下核心挑战:
- 公平性保障: 多个容器争抢 CPU 时,需要确保每个容器获得其承诺的份额,避免“吵闹邻居”效应。
- 突发流量处理: 容器在空闲后突然爆发请求,需要允许其使用闲置 CPU,但不能影响其他容器的保证份额。
- 延迟敏感型与批处理型混合部署: 低延迟业务(如 Web 服务)与高吞吐业务(如离线计算)共享 CPU 时,需要差异化调度策略。
- CPU 绑定与 NUMA 亲和性: 容器需要绑定特定 CPU 核心或 NUMA 节点,以优化缓存命中率和内存访问延迟。
- 监控与反馈: 实时获取容器的 CPU 使用率、节流时间、压力指标,用于自动扩缩容和异常检测。
常见陷阱: 仅配置
cpu.shares(或 cpu.weight)而不设置 cpu.cfs_quota_us(或 cpu.max),在 CPU 争抢时无法限制容器的最大使用量,可能导致高负载容器侵占其他容器的资源。