当某租户触发 OOM 时,如何自动熔断而不影响其他租户?
解读
国内大模型 SaaS 普遍采用“共享 GPU 池 + 多租户容器”架构,显存由所有租户共同占用。一旦某个请求把显存打爆,Linux OOM Killer 会随机挑进程杀掉,导致同卡其他租户一起 5xx,这是面试最想考察的“爆炸半径控制”能力。题目要求“自动熔断”,意味着系统必须在毫秒级发现租户级 OOM 风险,只阻断该租户,不杀进程、不掉卡,继续服务其他租户。因此回答必须围绕“租户维度显存预算隔离 + 实时感知 + 快速拒绝 + 优雅恢复”四层展开,并给出可落地的国产 GPU 栈方案(华为昇腾、寒武纪、燧原均类似)。
知识点
- 租户级显存配额(Quota):在 K8s 扩展调度器里为每个 Pod 注入
aliyun.com/gpu-mem: 16Gi这类扩展资源,由 Device Plugin 维护显存账本,实现硬限制而非仅 CUDA 显存申请。 - 实时显存采样:利用 DCGM + nvml 或 昇腾 msprof,每 100 ms 把已用显存 / 配额推送到 Prometheus,规则
((container_gpu_mem_used / container_gpu_mem_quota) > 0.95)产生 TenantOOM 事件。 - 熔断决策链:
- Sidecar 代理(Envoy + Lua 或 MOSN)监听事件,立即将该租户流量权重置 0;
- 同时把熔断标志写入 Redis 集群(TTL 30 s),推理网关看到标志直接返回 429 并带 Retry-After 头,不再转发到 GPU 节点。
- 零拷贝恢复:当采样值低于 80 % 且连续 3 个周期,Sidecar 自动恢复权重;若 5 分钟内仍反复触发,则锁定该租户 15 分钟并通知运营走人工扩容或模型分片。
- 进程级兜底:即使上述机制失效,cgroup v2 + nvidia-docker 的 memory.max 会把该容器显存压到配额,CUDA API 返回 out of memory,业务代码捕获后主动 abort 单条请求并记录 tenant_id,不抛异常到框架层,从而不重启 Pod。
答案
线上系统按“预算隔离 → 实时感知 → 快速拒绝 → 优雅恢复”四步闭环:
- 预算隔离:K8s 扩展调度器为每个租户 Pod 注入显存配额注解,Device Plugin 维护显存账本,超分比例不超过 1.2,保证物理上限可兜底。
- 实时感知:DCGM Exporter 每 100 ms 采集容器级显存使用率,Prometheus 规则触发 TenantOOM 事件,通过 Kafka 推送到 Sidecar 与推理网关。
- 快速拒绝:
- Sidecar 在 10 ms 内把该租户权重置 0,已排队请求继续执行但不再接收新请求;
- 推理网关看到 Redis 熔断标志,直接返回 429 并记录 tenant_id、gpu_id、timestamp,实现0 GPU 占用。
- 优雅恢复:采样值低于 80 % 且连续 3 周期,自动解除熔断;若 5 分钟内触发 ≥3 次,升级为人工扩容并通知租户降并发或切换小模型。
通过以上机制,单租户 OOM 爆炸半径 = 该租户自身,其他租户 P99 延迟零抖动,GPU 利用率保持 >75%,符合国内监管对“可审计、可回滚”要求。
拓展思考
- 国产卡适配:昇腾 910B 使用 Ascend Device Plugin 的 Ascend Memory Quota 特性,采样周期可缩短到 50 ms,但需把 Prometheus 规则中的 nvml 指标替换为 ascend_mte 指标。
- 多卡并行场景:当租户使用 张量并行(TP=4) 时,显存配额需按卡数等分,熔断信号需四卡同时触发才整体拒绝,否则会出现部分卡提前熔断导致 NCCL 死锁;实现上可在 Sidecar 层做 quorum 判断(3/4 卡触发才熔断)。
- 业务层回退:若租户签约了 SLA 99.9%,可在熔断后自动把请求路由到 CPU 量化模型(INT8),牺牲 20% 精度换取可用性,需提前在 ConfigMap 中维护模型路由表。
- 审计与合规:所有熔断事件必须写入 LTS(日志服务) 并加密落盘,保存 180 天,方便等保 2.0 现场核查;tenant_id 需脱敏为哈希值,避免泄露客户隐私。