路由、多副本与自动扩缩容
一句话定义
单副本之上,推理服务需要一层"懂 LLM"的路由与扩缩容:会话亲和与前缀感知路由保住 KV 复用收益,队列/并发类指标(而非 GPU 利用率)驱动扩容,Little's Law 用来把流量换算成副本数。
为什么重要
LLM 服务与传统无状态服务最大的不同:副本持有 KV 状态,会话被路由到不同副本会丢掉前缀缓存;而通用扩缩容指标(CPU/GPU 利用率)在 decode 场景严重失真。这一层的错误不会让服务挂掉,但会静默吃掉 30–70% 的吞吐。
前置知识
- Little's Law:L = λ × W(系统中平均请求数 = 到达率 × 平均停留时间)。
核心概念
- 会话亲和(session affinity):同一会话(或同一 API key/用户)固定路由到同一副本,使其多轮 KV 前缀缓存持续命中(kp-014 的共享块在副本内生效)。
- 前缀感知路由(prefix-aware routing):把请求按其 prompt 前缀哈希/最长匹配路由到"已有该前缀缓存"的副本——SGLang router 与 vLLM production stack 的核心思想;共享 system prompt 场景收益巨大。
- 负载均衡策略:round-robin 简单但无视 KV 状态;least-request 更稳;最优是"least-request + 前缀亲和"组合。
- 扩缩容信号:应使用
num_requests_waiting(队列深度)、P99 TTFT、并发数等应用层指标;GPU 利用率在 decode 场景虚高(kp-003),不可作扩容依据。
- 冷启动:模型加载与编译需分钟级,缩到零等于下线;应设 minReplicas ≥ 1 并做启动预热。
原理与机制
LLM 副本是"带状态的服务"——KV 缓存就是状态。路由层若随机分发,等于每次请求都让既有缓存作废;会话亲和与前缀感知路由把"状态在哪里"作为调度的第一输入,用一次哈希换取整段 prefill 的复用。扩缩容同理:decode 场景的资源画像是带宽占满而 SM 虚高,因此信号必须取自应用层指标(队列深度、TTFT/TPOT P99),而非硬件利用率。
公式与模型
Little's Law 容量换算:
λ_peak 峰值 QPS,W̄ 平均请求时长(如 8s),C 单副本安全并发(由 kp-022 压测得出,如 48),1.3 为冗余系数。例:峰值 20 QPS × 8s = 160 并发 → 160/48×1.3 ≈ 4.3 → 5 副本。
图示
客户端 → 网关 → LLM Router(前缀哈希+least-request) → [副本1: promptP 缓存热]
→ [副本2: promptQ 缓存热]
同前缀请求都进副本1 → KV 复用 → TTFT 显著下降
实例或案例
客服机器人案例:全量共享 2k token system prompt。round-robin 下每个副本都要为每个会话重算 prefill;改为前缀感知路由后 system prompt 块只算一次并在副本内长期驻留,TTFT P99 从约 1.8s 降到约 0.4s。改造仅发生在路由层——这是"不动引擎拿到数量级收益"的典型案例。
常见误区
- "GPU 利用率高就该扩容":decode 场景 SM 占用虚高,正确信号是队列深度与 TTFT/TPOT P99。
- "LLM 服务是无状态的":KV 缓存就是状态;随机路由会系统性摧毁缓存命中。
- "扩容只看 QPS":同一 QPS 下,长输出流量与短输出流量的并发承载差 10 倍,必须用并发数(λ×W)而非裸 QPS。
- "HPA 用默认 CPU 指标即可":GPU 机器上 CPU 指标几乎无信息量;接自定义 metrics(vLLM /metrics + Prometheus adapter)。
自测题
- 用 Little's Law:峰值 50 QPS、平均请求 4s、单副本安全并发 40、冗余 1.3,求副本数。
要点:50×4/40×1.3 = 6.5 → 7 副本。
- 为什么 GPU 利用率不能当扩容信号?
要点:decode 访存密集但 SM 被占满,指标虚高,无法反映真实饱和度。
- 前缀感知路由在什么流量下收益最大?
要点:前缀高度重复(共享 system prompt、多轮会话、模板化任务)的流量。
与其他知识点的关系
kp-014 的前缀共享是本页收益的物理基础;kp-017 的低温确定性输出让缓存命中更稳;kp-028 把副本数换算成钱;kp-024 是路由的进一步形态(按阶段路由)。
延伸阅读
SGLang 论文(Zheng 等,2023)中 RadixAttention 与前端路由协同的设计,是前缀感知路由的代表实现。