自动扩缩容 Autoscaling

Autoscaling (HPA / VPA / KEDA / Queue-based)

根据实时负载指标自动增减计算资源副本数或规格,平衡服务性能与成本,避免流量高峰与低谷时的资源浪费或不足

详细解释

自动扩缩容(Autoscaling,简称 AS)是云原生与大模型推理服务中的核心资源调度能力,指系统根据实时负载(如 GPU/CPU 利用率、请求队列深度、P99 延迟、QPS、消息队列堆积长度等)在无人干预的前提下,自动增加副本数(扩容)或减少副本数(缩容),从而在「流量高峰时避免服务雪崩」与「流量低谷时避免算力浪费」之间达成最优平衡。对 LLM 推理服务来说,单个 GPU 副本每小时费用高达几十元,自动扩缩容通常可在不降低 延迟百分位 的前提下,将月度 GPU 成本下降 30% 至 60%。

自动扩缩容的实现谱系可分为五大类:(1) HPA(Horizontal Pod Autoscaler,水平扩缩容):Kubernetes 原生方案,基于 CPU/GPU 利用率、自定义指标增减 Pod 副本数,最通用;(2) VPA(Vertical Pod Autoscaler,垂直扩缩容):自动调整单个 Pod 的 CPU/GPU/内存规格,适合有状态服务或单机就能扛住的轻量场景;(3) KEDA(Kubernetes Event-Driven Autoscaling):事件驱动扩缩容,基于 Kafka/RabbitMQ/Redis 队列长度、Prometheus 自定义指标等扩缩容,对异步批处理任务极友好;(4) 队列驱动(Queue-based)的 LLM 专用扩缩容:基于推理请求在 GPU 前排队的平均等待时长、Pending 请求数、P99 延迟阈值等触发;(5) 预测式扩缩容(Predictive):基于历史流量模式(如每天 9-12 点高峰)提前扩容,彻底消除 HPA 「滞后反应」的冷启动空窗。

唯元智创 的 API 网关默认提供「预测 + 队列驱动 + HPA」的三级混合自动扩缩容:预测层提前 30 分钟为可预期的历史高峰预热 20% 至 30% 副本;队列驱动层在 P99 排队等待时长超过 200ms 时秒级触发扩容;HPA 做兜底的 CPU/GPU 利用率兜底;同时每 24 小时回放近 7 天真实流量与成本曲线,持续优化「目标利用率 / 扩容阈值 / 缩容冷却时间」三组参数。也可与 多地域容灾 的跨地域负载调度结合使用。

五种主流自动扩缩容方案对比表

方案名称核心指标来源扩容反应速度适合场景LLM 推理适配度落地复杂度月度 GPU 成本节省率推荐度
HPA 水平扩缩容(原生 K8s)CPU/GPU 利用率、QPS慢(1 至 3 分钟)通用 Web/API中(利用率指标滞后)极低25% 至 40%⭐⭐⭐⭐
VPA 垂直扩缩容历史资源用量慢(小时级/天级)单实例有状态服务、数据库低(GPU 规格难动态改)15% 至 25%⭐⭐⭐
KEDA 事件驱动队列长度、Cron、自定义 PromQL中(秒级至 1 分钟)异步批处理、离线任务高(离线推理/队列型)35% 至 55%⭐⭐⭐⭐⭐(异步场景)
Queue-based 队列驱动(LLM 专用)请求排队时长、Pending 数、P99 延迟快(10 秒级)LLM 在线推理、实时对话极高中高40% 至 60%⭐⭐⭐⭐⭐(在线 LLM)
Predictive 预测式历史流量时间序列 + ML 预测最快(提前 5 至 60 分钟)有明显日/周规律流量高(提前预热消除冷启动)40% 至 65%⭐⭐⭐⭐

实战经验与避坑

  1. LLM 在线推理的扩容触发指标一定不能只用「GPU 利用率」,必须引入「排队等待时长」:GPU 利用率是天然滞后的指标——当 GPU 利用率达到 70% 时,请求已经在队列里堆了好几十毫秒,P99 延迟已经暴涨;正确做法是用「推理请求队列平均等待时长(如 >200ms 连续 30 秒)」或「Pending 请求数 / 运行中副本数 > 某阈值」作为第一优先扩容触发,GPU 利用率做第二兜底;实践中仅这一项改动,P99 延迟就能比纯 GPU-HPA 下降 30% 至 50%。
  2. 缩容必须极度保守,冷却时间要比扩容慢 5 至 10 倍:扩错了(多开了几台 GPU)只是多花几十几百块钱;缩错了(把正在处理长请求的 Pod 杀了)会直接导致正在生成中的 20 至 100 条请求失败返回 5xx,用户体验严重受损,且 错误预算 被快速消耗。正确做法:① 缩容冷却窗口设 10 至 30 分钟,扩容冷却仅 1 至 2 分钟;② 缩容前先给 Pod 打 Draining 标记,停止接新请求,等待所有进行中请求处理完毕再 Kill;③ 每次缩容最多杀 N-1 副本中的 10% 至 20%,不做断崖式缩容。
  3. 务必留 5% 至 10% 的「永久热备副本」,即使利用率低也不缩:真实线上永远会有不可预期的流量脉冲(如一条小红书/微博火了、一次营销活动提前、某个大客户流量突增 5 倍),如果所有副本都按「刚好够用」来配,脉冲到来时 HPA 的 2 至 3 分钟冷启动时间足以让 P99 延迟冲到 30 秒以上,SLA 直接穿底;维持少量热备的成本极低(相比每次事故赔付 + 客户流失可忽略),却能在 90% 的脉冲场景下救场。
  4. HPA 目标利用率设置有黄金区间:LLM 推理推荐目标 GPU 利用率 = 60% 至 70%,不要设到 85% 以上:大模型推理的单个请求负载方差极大(输入 1K 输出 50 和输入 32K 输出 4K 的耗时可能差百倍),如果目标利用率设 85%,在真实方差下,平均 85% 的系统会有 30% 的时间跑到 95% 以上甚至 GPU OOM,尾部 P99 延迟会出现灾难性爆炸;60% 至 70% 的目标利用率是在「方差容忍」和「成本节省」之间的 Pareto 最优点,长期看综合成本最低。
  5. 预测式扩缩容的训练集必须剔除异常日,否则会放大错误:如果你的历史数据里包含「618 / 双 11 促销」「系统故障日」「周末异常低流量」这类特殊日子,不加过滤直接喂给预测模型,预测出来的曲线会在普通日错误地预测出高峰,导致不必要的 GPU 浪费;正确做法是先对历史流量做 3σ 异常剔除 + 日历特征(工作日/节假日/特殊活动标签)打标,再预测,普通日的预测准确率通常可达到 85% 至 93%。
  6. 新模型/新地域上线前务必做「扩容演练」,不要等真实流量来了才发现扩不起来:常见的扩容失败陷阱包括:① GPU 配额不够(云厂商给的总 A100 上限 16 卡,HPA 想扩到 20 卡直接失败);② 镜像拉取时间过长(大镜像 + PVC 挂载导致 Pod 启动要 8 分钟);③ 模型权重加载慢(未预热的权重冷启动花 5 分钟以上);④ 网络安全组/Service Mesh sidecar 注入失败。这些问题在流量真实来临前完全可以通过「手动扩容演练 + PDB/Disruption Budget 验证」提前发现并解决。

常见问题

大模型推理冷启动要 2-5 分钟,HPA 反应慢导致 P99 暴涨怎么办?
用「预热冷备 + 预测式提前扩容 + 队列驱动快速触发」三位一体方案,冷启动空窗期可从 5 分钟压到 1 分钟以内甚至完全消除:第一步也是最有效的一步——维持永久预热冷备池。比如你的高峰需要 20 张 GPU,平时 10 张,那永远保持 12 张处于 Running 状态(其中 2 张是热备,当前利用率极低),并且这 12 张都已经加载好模型权重、Warm-Up 过一批样例请求,接到流量 1 秒内即可开工;真实峰值到来时,冷备先顶上,为 HPA 真正拉起额外副本赢得 5 至 10 分钟的缓冲时间。第二步,预测式提前扩容。用过去 4 周历史流量数据按 5 分钟粒度训练 Prophet / XGBoost 时序模型,提前 30 分钟预测到即将到来的高峰并提前扩容,真实用户完全感觉不到冷启动;对有明显日周期规律(9 至 12、14 至 18、20 至 23 三段高峰)的场景,仅预测式一项就能覆盖 70% 以上的扩容需求。第三步,把扩容触发从「GPU 利用率 70%」改为「队列等待时长大于 200ms」。队列等待时长比 GPU 利用率早感知 30 至 60 秒,触发扩容更及时。若仍嫌慢,可加「Pending 请求数大于运行中副本数乘 2」作为第二触发条件。最后加一个兜底:镜像预热 + 本地权重缓存。把模型权重和镜像存在节点本地 SSD(或分布式文件缓存),Pod 启动时不再跨网络拉 50GB 权重文件,冷启动时间从 5 分钟降到 40 秒,HPA 效果立即翻倍。四项一起落地,绝大多数业务的峰值 P99 延迟波动能控制在 30% 以内,完全可以在用户感知不到的前提下平稳扛住 3 至 5 倍流量脉冲。
怎么判断我该省成本还是该保体验?目标利用率到底定多少?
决策依据是「错误预算消耗速度 + 业务敏感度」,并由此倒推出目标利用率的安全区间:正确的三步决策法——第一步,先确定业务敏感度等级,把业务分成三档:A 档(体验敏感):语音通话、视频会议、金融交易、付费用户实时对话助手、ToB 核心 SLA 产品。此档错误预算耗尽等于直接丢客户,目标利用率推荐 50% 至 60%,永久热备 15% 至 20%,宁可多花成本不可穿底;B 档(平衡):普通 C 端产品、知识问答、内容生成、非核心客服。此档 P99 偶尔小超标但不能持续,目标利用率推荐 60% 至 70%,永久热备 5% 至 10%,是绝大多数产品的默认档;C 档(成本敏感):离线批处理、数据生成、评测脚本、非实时训练。此档允许排队和延迟,只要最终跑完即可,目标利用率推荐 80% 至 90%,可不用热备,成本优先。第二步,看错误预算消耗速度。如果你的月度 99.9% 可用性 SLA(允许 43 分钟停机每月),在每月 10 号就已经消耗了 30% 以上的预算,说明当前目标利用率设置过高,必须下调 5% 至 10%;反之如果到了月底只消耗了 10% 预算,且 P99 延迟一直远低于阈值,说明可以大胆上调目标利用率 5% 个点来省钱。第三步,每月做一次 A 斜杠 B,寻找 Pareto 最优点。每周末把其中一个可用区(AZ)的目标利用率上调 5%,另一个 AZ 保持不变,对比两组的「P99 延迟波动对比成本节省」,持续 3 至 6 个月后就能找到属于你自己业务的精确最优点,通常比通用默认值还能再多省 5% 至 10% 成本而不降低体验。最终目标永远不是最低成本,而是「错误预算稳定 30 天消耗 60% 至 80%,月底有少量结余」。
KEDA 和 LLM 专用 Queue-based 扩缩容选哪个?混合部署可行吗?
两者不是「二选一」,而是「异步用 KEDA,在线用 LLM Queue-based」的最佳分工;混合部署 100% 可行且推荐:先看适用边界——KEDA 最擅长异步批处理任务(如离线批量做评测、50 万条数据做 Embedding、夜间生成报告、视频字幕批处理等),任务天然堆积在 Kafka 斜杠 Redis 斜杠 RabbitMQ 队列里,KEDA 看队列长度直接扩 Pod,扩起来后一条条消费,任务失败也可重试,不在乎冷启动慢。对于 LLM 异步任务,KEDA 的 ScaledObject 加 Kafka PromQL 触发(lag 数除以每 Pod 每秒处理数等于目标副本数)非常成熟,是首选。LLM 专用 Queue-based 扩缩容最擅长在线实时对话(用户在 App 里发消息等首字返回),核心诉求是「排队时长毫秒级感知 + 快速扩容 + 正在处理请求不被杀」。这类场景 Pod 前面的请求队列不是消息中间件,而是 vLLM 斜杠 Text Generation Inference 等推理引擎自带的内存 Continuous Batching 队列,KEDA 看不到这么深的指标,必须由 LLM 推理框架的 Controller 或自定义 Prometheus Exporter 暴露「Pending 请求数、平均排队时间、Per-Request 阶段耗时」等细粒度指标,再由自定义 Scaler(或 KEDA 的 Prometheus Scaler 自定义 PromQL)做扩缩容决策。结论:混合部署是业界主流最佳实践。一套 LLM 平台上同时跑在线加离线两类任务,就部署两套 Scaler:其一 在线流量池:用 LLM 专用 Queue-based 加预测式扩容,目标利用率 60% 至 70%,热备 10%,严格保障 P99;其二 离线任务池:用 KEDA 加 Kafka 斜杠 Redis 队列驱动,目标利用率 85% 至 90%,允许排队,只追求 GPU 100% 不浪费。两者资源池逻辑隔离(通过 Node Affinity 加 Taint 斜杠 Toleration 分开),但在线池空闲 30 分钟以上的 GPU 可临时借调给离线池用(即「资源超卖 + 弹性抢占」),通过 Kueue 斜杠 Volcano 这类批处理调度器实现,整体 GPU 利用率还能再提升 15% 至 25%。最后加一个优先级抢占:在线任务优先级永远高于离线,一旦在线池需要扩容,立即杀掉占用借用 GPU 的离线 Pod 还给在线(离线 Pod 有重试机制不丢数据),实现「体验 + 成本」双优——这也是 唯元智创 平台默认的资源调度策略。