容器 CPU share 1024 与 limit 2 核的区别,如何量化对压测结果的影响

解读

面试官想确认三件事:

  1. 你是否真的在 Linux CFS 调度器层面理解“share”与“limit”的生效机制;
  2. 能否把抽象的内核参数翻译成可观测、可对比的压测指标;
  3. 是否具备“量化差异 → 定位瓶颈 → 给出调优建议”的闭环能力。
    国内主流生产环境 90% 以上基于 Kubernetes + Docker,宿主机多为 16C/32G 或 32C/64G 规格,Cgroup v1 仍占大头,v2 逐步上线。回答必须紧扣“如何设计实验、采集数据、解释结果”,而不是背概念。

知识点

  1. CPU share(–cpu-shares 或 k8s cpu request)
    – 相对权重,只在容器竞争 CPU 时生效;空闲时可被超额使用。
    – 权重值与核数无直接换算关系,1024 代表“默认权重”,同宿主机上 2048 的容器可获约 2 倍调度机会。

  2. CPU limit(–cpus 或 k8s cpu limit)
    – 硬上限,由 CFS quota(period=100 ms)实现:limit=2 核 ⇒ 每 100 ms 周期内最多跑 200 ms 的 CPU 时间片。
    – 达到上限即被 throttle,线程进入就绪队列等待下一个周期。

  3. 压测可观测指标
    – 应用层:QPS、P99 响应时间、错误率。
    – 容器层:container_cpu_usage_seconds_total、container_cpu_cfs_throttled_periods_total、container_cpu_cfs_throttled_seconds_total。
    – 宿主机层:%usr、%sys、run queue length、上下文切换。

  4. 量化方法
    – 控制变量:固定 Pod 数、副本数、网络、内存无限制,线程池/连接池打满。
    – 阶梯负载:用 Gatling/JMeter 从 50 并发逐级加到 2000,步长 5 min。
    – 对比矩阵:同一镜像分别跑“share=1024 无 limit”与“limit=2 核”两组,采集上述指标。
    – 差异计算:
    ΔQPS = (QPS_share – QPS_limit) / QPS_share
    ΔP99 = (P99_limit – P99_share) / P99_share
    throttle_ratio = Σthrottled_seconds / Σelapsed_seconds

答案

“share 1024”只决定宿主机 CPU 紧张时的相对优先级,空闲时可跑到 8 核甚至更多;“limit 2 核”是硬顶,哪怕宿主机空闲也不能超出。
量化步骤如下:

  1. 在 32C 宿主机起两个同名 Deployment,A 组 request=limit=2 核,B 组 request=1024 share、limit 不设置。
  2. 用 Gatling 以 500 并发压同一接口 10 min,指标如下:
    – A 组:CPU 使用率被钳在 200%,throttle_ratio=18%,QPS=5 800,P99=120 ms。
    – B 组:CPU 使用率冲到 420%,throttle_ratio=0,QPS=9 200,P99=65 ms。
  3. 计算差异:ΔQPS=–37%,ΔP99=+85%,说明 limit 2 核直接把吞吐腰折,长尾延迟翻倍。
  4. 若将 limit 提到 4 核,throttle_ratio 降到 2%,QPS 回升到 8 900,P99 降到 70 ms,基本与无 limit 持平,证明瓶颈就是 CPU 时间片被强制回收。
  5. 输出调优建议:
    – 对延迟敏感的核心链路,limit 至少给到压测峰值 CPU 利用率+30% 冗余;
    – 对离线任务可保留低 limit 以提升宿主机装箱率;
    – 在 K8s 中采用 VPA/HPA 结合历史 CPU 95 分位自动修正 limit,避免人工拍脑袋。

拓展思考

  1. 混部场景:夜间离线 Spark 任务 share=512,白天在线服务 share=2048,同一宿主机如何防止离线任务白天抢 CPU?
    – 可引入 kernel 的 cpu.qos_level 或阿里 koordinator 的 CPU 压制策略,动态下调离线权重。

  2. Cgroup v2 的 cpu.max="max 100000" 与 cpu.weight=100 如何映射到旧参数?
    – weight=100 ≈ shares=1024,但 v2 不再区分 limit 与 quota,需要把 cpu.max 写成“<quota> <period>”格式,调试时直接用 systemd-cgtop 观察。

  3. 超线程对量化结果的影响:
    – 同物理核超线程逻辑 CPU 共享执行单元,limit 2 核若被调度到同核超线程,实际算力 < 2 物理核;压测时需关闭超线程或绑定 core 以消除噪声。