3. Scaler 机制详解:Scaler 的分类与注册发现

Scaler(缩放器)是 KEDA 的核心抽象,负责连接外部事件源并返回事件指标数据,驱动 HPA 对工作负载进行弹性伸缩。理解 Scaler 的分类与注册发现机制,是正确配置事件源和构建流水线触发器的前提。

3.1 Scaler 的分类

KEDA 将 Scaler 分为两大类:内置 Scaler(Built-in Scaler)和外部 Scaler(External Scaler)。两者的核心区别在于实现方式、维护主体和部署形态。

对比维度 内置 Scaler(Built-in) 外部 Scaler(External)
实现方式 KEDA 核心代码仓库内维护,Go 语言实现 独立 gRPC 服务,任何语言均可实现
维护主体 KEDA 社区官方维护 第三方开发者或企业自行维护
部署形态 随 KEDA Operator 进程一起运行 独立 Deployment + Service,需额外部署
注册方式 编译时注册,启动时自动加载 通过 ClusterTriggerAuthentication 或 ScaledObject 中指定地址
典型场景 Kafka、Prometheus、RabbitMQ、AWS SQS 等 自研监控系统、私有协议、遗留中间件

3.1.1 内置 Scaler

内置 Scaler 是 KEDA 官方提供的事件源适配器,覆盖了主流的消息队列、数据库、监控系统和云服务。截至 KEDA 2.14,官方已提供超过 50 种内置 Scaler。常见分类如下:

  • 消息队列类:Apache Kafka、RabbitMQ、AWS SQS/SNS、Azure Service Bus、GCP Pub/Sub、NATS、Redis Streams
  • 数据库类:PostgreSQL、MySQL、MongoDB、Redis、Cassandra、DynamoDB
  • 监控与指标类:Prometheus、Datadog、New Relic、Azure Monitor、AWS CloudWatch
  • CI/CD 与工作流类:Jenkins、GitHub Actions、GitLab CI、Argo Workflows
  • HTTP 与自定义类:HTTP Add-on(基于请求速率)、Cron(定时伸缩)、Metrics API(自定义指标端点)
推荐原则:优先使用内置 Scaler。内置 Scaler 经过社区充分测试,性能稳定,且无需额外部署 gRPC 服务,降低运维复杂度。

3.1.2 外部 Scaler

当内置 Scaler 无法满足需求时(例如对接自研监控系统、私有协议或遗留中间件),可以通过外部 Scaler 扩展 KEDA 的事件源能力。外部 Scaler 本质上是一个独立的 gRPC 服务,必须实现 KEDA 定义的 ExternalScaler 接口。

外部 Scaler 的 gRPC 接口定义如下(protobuf):

service ExternalScaler {
  // 返回 Scaler 是否处于活动状态
  rpc IsActive(ScaledObjectRef) returns (IsActiveResponse);

  // 返回当前指标值,KEDA 据此计算目标副本数
  rpc GetMetricSpec(ScaledObjectRef) returns (GetMetricSpecResponse);

  // 返回指标快照值(可选,用于更精确的缩放决策)
  rpc GetMetrics(GetMetricsRequest) returns (GetMetricsResponse);

  // 关闭 Scaler 时的清理操作
  rpc Close(ScaledObjectRef) returns (CloseResponse);
}

3.2 Scaler 注册与发现机制

KEDA 通过一套清晰的注册与发现流程,将 Scaler 与 ScaledObject 绑定,实现事件驱动的弹性伸缩。下图展示了 Scaler 从注册到被调用的完整链路。

Scaler 注册与发现机制流程图 内置 Scaler 注册流程 1. 编译时:import scaler 包 2. init() 函数调用 Register() 3. 注册到全局 scalerMap 4. KEDA 启动时自动加载 5. 通过 ScaledObject 中 type 字段匹配 外部 Scaler 注册流程 1. 开发者实现 gRPC 服务 2. 部署为独立 Pod + Service 3. ScaledObject 中指定 address 4. KEDA 通过 gRPC 连接发现 5. 运行时动态注册与调用 ScaledObject 解析 Scaler 类型 type: "kafka" → 内置 | type: "external" → 外部 Scaler 调用与指标获取 KEDA 定时调用 Scaler 的 IsActive() / GetMetrics() 返回指标值 → HPA 计算目标副本数 → 调整 Deployment

3.2.1 内置 Scaler 的注册机制

内置 Scaler 采用编译时注册 + 启动时自动加载的模式。每个内置 Scaler 在 pkg/scalers/ 目录下独立实现,通过 init() 函数调用 Register() 方法将自身注册到全局的 scalerMap 中。

注册核心代码示例:

// pkg/scalers/kafka_scaler.go
func init() {
    // 注册 Kafka Scaler,key 为 "kafka"
    Register("kafka", func() Scaler {
        return &kafkaScaler{}
    })
}

// pkg/scalers/registry.go
var scalerMap = make(map[string]ScalerBuilder)

func Register(name string, builder ScalerBuilder) {
    scalerMap[name] = builder
}

func GetScaler(name string) (Scaler, bool) {
    s, ok := scalerMap[name]
    return s, ok
}

当用户创建 ScaledObject 时,KEDA 的控制器会解析 spec.triggers[].type 字段,从 scalerMap 中查找对应的 Scaler 构建器,实例化后开始拉取指标。

3.2.2 外部 Scaler 的发现机制

外部 Scaler 采用运行时动态发现 + gRPC 连接的模式。KEDA 不预先注册外部 Scaler,而是在 ScaledObject 中通过 spec.triggers[].metadata.address 字段指定外部 Scaler 的 gRPC 服务地址。

外部 Scaler 的 ScaledObject 配置示例:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: custom-scaledobject
spec:
  scaleTargetRef:
    name: my-deployment
  triggers:
  - type: external
    metadata:
      # 外部 Scaler 的 gRPC 服务地址
      address: custom-scaler.namespace.svc.cluster.local:9090
      # 传递给外部 Scaler 的自定义参数
      topic: my-topic
      threshold: "100"
    authenticationRef:
      name: custom-scaler-auth
关键区别:内置 Scaler 的 type 字段直接使用 Scaler 名称(如 kafka、prometheus),而外部 Scaler 的 type 字段固定为 external,通过 address 元数据指定实际服务位置。

3.3 Scaler 生命周期管理

KEDA 对每个 Scaler 实例进行完整的生命周期管理,确保资源正确释放和指标持续可用。

阶段 内置 Scaler 外部 Scaler
初始化 ScaledObject 创建时,从 scalerMap 构建实例 ScaledObject 创建时,建立 gRPC 连接
指标拉取 KEDA 定时调用 GetMetrics(),默认每 30 秒一次 通过 gRPC 流式或轮询调用 GetMetrics()
健康检查 内置在 KEDA Operator 进程中,随进程存活 KEDA 定期发送 gRPC 健康检查请求
销毁 ScaledObject 删除时,调用 Close() 清理资源 ScaledObject 删除时,关闭 gRPC 连接

3.4 选择 Scaler 类型的决策指南

在实际项目中,选择内置 Scaler 还是外部 Scaler,可以参考以下决策树:

Scaler 类型选择决策树 事件源是否官方支持? 是 → 使用内置 Scaler 否 → 考虑外部 Scaler 实现 gRPC 接口并部署为独立服务 ScaledObject 中 type: external + address ScaledObject 中 type: "kafka" 等 无需额外部署,KEDA 自动管理
注意事项:外部 Scaler 虽然灵活,但引入了额外的网络依赖和运维成本。建议仅在以下场景使用:
1. 对接自研或私有化监控系统;
2. 需要自定义复杂的指标计算逻辑;
3. 内置 Scaler 无法满足性能或功能需求。

3.5 小结

Scaler 是 KEDA 事件驱动伸缩的核心抽象。内置 Scaler 通过编译时注册、启动时自动加载的方式提供官方事件源支持;外部 Scaler 通过 gRPC 接口实现运行时动态发现,扩展了 KEDA 的生态边界。理解两者的注册与发现机制,有助于在流水线构建触发器集成时正确选择 Scaler 类型,并合理配置 ScaledObject 的触发器参数。