游戏卡顿白皮书 › L7 服务器操作系统(内核)
容器 CPU 限流(CFS 配额) Container CPU throttling (CFS quota)
原因 ID so-cpu-quota · 主责 运维团队·系统运维 · 配合 研发团队·服务器开发
在含图示和实验的完整版中打开此卡片 →
给容器设置 CPU 上限后,一旦在规定周期(通常为 100 ms)内用完配额,周期剩下的时间里就会被强制停住(限流)。
起因 在 Kubernetes 等环境中给游戏服务器容器设置了 CPU 上限(limit) → 结果 tick 计算集中的时刻用完配额,停住几十 ms,直到下一个周期 → 画面表现 平均 CPU 不高,tick 却周期性冲高,表现为一卡一卡、慢动作
- 症状
- 一卡一卡, 慢动作
- 因素
- 停顿, 抖动
- 谁会遇到
- 全服
- 何时出现
- 人多的时候, 偶尔随机
- 负责方
- 主责 运维团队·系统运维 · 配合 研发团队·服务器开发
- 研发团队要做的事
- 让工作线程数与 CPU 上限匹配(避免运行时按宿主机的全部核心数创建线程)。
- 运维团队要做的事
- 给足 CPU 上限或去掉上限,分配独占核心;监控被限流的次数(nr_throttled)。
- 数值参考
- 上限为 2 核的服务器上有 8 个线程同时工作时,100 ms 周期的配额 25 ms 就用完了,剩下 75 ms 都在停住。
- 监控图上
- 随人数/负载上升 · 限流次数(nr_throttled)、服务器 tick 耗时
- 查看位置
- 在容器 cgroup 的 cpu.stat 中看 nr_throttled、throttled_usec(cgroup v1 为 nr_throttled、throttled_time)的增量,与服务器 tick 耗时一起看
- 确认依据
- 平均 CPU 使用率低于上限,nr_throttled、throttled_usec 却持续增加,且与 tick 冲高的时刻重合
- 排除依据
- nr_throttled 不增加则不是这个原因。虚拟机本身被挤占,看“CPU 窃取时间(虚拟机)”
- 确认手段
- 运维工具即可确认(无需游戏代码)
出处
- CFS Bandwidth Control Linux kernel
每个周期分到的配额用完后,线程停住直到下一个周期(限流);默认周期 100 ms;nr_throttled 统计 - Control Group v2 Linux kernel
cpu.max 的格式为“$MAX $PERIOD”(配额、周期),默认值为“max 100000”(100 ms 周期) - Resource Management for Pods and Containers Kubernetes
容器的 CPU limit 是内核通过 CPU 限流强制执行的硬上限
相关原因
同一层:L7 服务器操作系统(内核)
其他层中同样导致“一卡一卡”的原因
查看含图示和实验的原卡片