4. KPA 工作原理:基于请求并发度的缩放算法

Knative Pod Autoscaler (KPA) 是 Knative Serving 的默认 Pod 水平自动缩放器。与基于 CPU/内存的 HPA 不同,KPA 的核心缩放指标是请求并发度 (Concurrency),即每个 Pod 正在处理的并发请求数量。KPA 通过精确控制并发度,实现更快速、更平滑的弹性伸缩,特别适合无服务器工作负载。

4.1 核心缩放指标:请求并发度

KPA 不依赖资源利用率,而是直接观测请求并发数。其数据来源是 Activator 或 Queue-Proxy 边车容器上报的指标。

指标 说明 数据来源
Average Concurrency (AvgConc) 所有 Pod 的平均并发请求数 Queue-Proxy 边车
Pod Concurrency 单个 Pod 当前正在处理的请求数 Queue-Proxy 边车
Requests per Second (RPS) 每秒请求数(可选指标) Queue-Proxy 边车
关键公式: 期望 Pod 数 = ceil( 当前总并发数 / 目标并发度 (Target Concurrency) )

4.2 Panic 模式与 Stable 模式

KPA 设计了两种缩放模式:Stable 模式(稳定模式)和 Panic 模式(恐慌模式),以平衡缩放稳定性与响应速度。

4.2.1 Stable 模式(稳定模式)

在正常情况下,KPA 运行在 Stable 模式。它使用一个较长的观察窗口(默认 60 秒)来计算平均并发度,避免因瞬时流量波动导致频繁扩缩容。

  • 窗口大小: 60 秒
  • 行为: 平滑、保守,适合稳态流量
  • 适用场景: 流量平稳或缓慢增长

4.2.2 Panic 模式(恐慌模式)

当流量突发,并发度在短时间内急剧上升时,KPA 会进入 Panic 模式。它切换到一个更短的观察窗口(默认 6 秒),以更激进的速度进行扩容,快速响应突发流量。

  • 触发条件: 在 60 秒窗口内,平均并发度达到目标并发度的 2 倍(即 panic-threshold = 2.0)
  • 窗口大小: 6 秒
  • 行为: 快速扩容,可能跳过稳定模式的计算
  • 退出条件: 并发度回落至目标并发度的 1.1 倍以下,持续 60 秒
设计意图: Panic 模式是为了应对“流量尖峰”而设计的。它牺牲了部分稳定性,换取了更快的扩容速度,确保在流量突增时不会发生请求排队或超时。

下图展示了 KPA 在 Stable 和 Panic 模式下的状态转换与决策流程:

KPA Panic 与 Stable 模式状态转换图 KPA Panic 与 Stable 模式状态转换 Stable 模式 窗口: 60s | 平滑缩放 Panic 模式 窗口: 6s | 快速扩容 并发度 ≥ 2× 目标值 (panic-threshold) 并发度 ≤ 1.1× 目标值 持续 60s 缩放决策 期望 Pod 数 = ceil( 总并发数 / 目标并发度 )

4.3 目标并发度 (Target Concurrency) 配置

Target Concurrency 是 KPA 缩放算法的核心参数,它定义了每个 Pod 期望处理的并发请求数。KPA 通过调整 Pod 数量,使实际并发度尽量接近此目标值。

4.3.1 配置方式

目标并发度可以在 Knative Service 的 YAML 中通过 Annotation 或 Revision Template 配置。

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: hello-world
spec:
  template:
    metadata:
      annotations:
        # 设置目标并发度为 10
        autoscaling.knative.dev/target: "10"
        # 可选:设置目标 RPS(如果使用 RPS 模式)
        # autoscaling.knative.dev/target-utilization-percentage: "70"
    spec:
      containers:
        - image: gcr.io/knative-samples/helloworld-go

4.3.2 参数详解

参数 默认值 说明
autoscaling.knative.dev/target 100 每个 Pod 的目标并发请求数。KPA 会尽量维持此并发度。
autoscaling.knative.dev/target-utilization-percentage 70% 目标利用率百分比。KPA 实际维持的并发度 = target × utilization。例如 target=10, utilization=70%,则实际目标为 7 并发。
autoscaling.knative.dev/metric concurrency 缩放指标。可选 concurrency 或 rps。
配置建议: 不要将 target 设置得过低(如 1),否则会导致 Pod 数量过多,增加调度开销和资源碎片。通常建议根据应用的单 Pod 处理能力进行设置,例如 10-100 之间。

4.3.3 缩放算法示例

假设当前有 3 个 Pod,每个 Pod 的并发数分别为 [8, 12, 10],目标并发度设置为 10:

  1. 计算总并发数: 8 + 12 + 10 = 30
  2. 计算期望 Pod 数: ceil(30 / 10) = 3
  3. 当前 Pod 数: 3
  4. 决策: 无需扩缩容

如果流量突增,并发数变为 [20, 25, 18]:

  1. 计算总并发数: 20 + 25 + 18 = 63
  2. 计算期望 Pod 数: ceil(63 / 10) = 7
  3. 决策: 扩容至 7 个 Pod

4.4 缩放算法流程图

下图展示了 KPA 从指标采集到最终执行扩缩容的完整算法流程:

KPA 缩放算法流程图 KPA 缩放算法流程图 1. 指标采集 2. 计算平均并发度 3. 判断 Panic 条件 4a. 使用 6s 窗口 4b. 使用 60s 窗口 5. 计算期望 Pod 数 6. 执行扩缩容 是 (Panic) 否 (Stable)

4.5 关键设计考量

  • 避免抖动: Panic 模式退出有 60 秒冷却期,防止频繁模式切换导致 Pod 震荡。
  • 目标利用率: 通过 target-utilization-percentage 预留缓冲,避免 Pod 刚好达到目标并发度后立即触发扩容。
  • 缩容保护: KPA 默认有缩容冷却期(默认 60 秒),防止流量短暂下降时过度缩容。
  • 零流量缩零: 当并发度降为 0 时,KPA 会将 Pod 数缩至 0(如果配置了 min-scale: 0)。
最佳实践: 对于延迟敏感型应用,建议将 target-utilization-percentage 设置为 50%-70%,留出足够的突发处理能力;对于批处理或异步任务,可以设置为 80%-90%,提高资源利用率。