4. Scaler 概念与分类
Scaler 是 KEDA 的核心抽象,负责从外部事件源(如 Kafka、RabbitMQ、Prometheus、AWS SQS 等)拉取指标数据,并基于这些数据计算出期望的副本数。KEDA 通过 Scaler 将事件驱动的弹性伸缩能力与 Kubernetes HPA 解耦,使得任何事件源都可以成为触发扩缩容的信号。
4.1 Scaler 的定义
在 KEDA 中,Scaler 是一个实现了特定接口的组件,它完成以下三项职责:
- 指标获取:从外部系统(消息队列、数据库、监控系统等)拉取实时指标值。
- 阈值比较:将当前指标值与用户定义的阈值(如
messageCount > 10)进行比较。 - 副本计算:根据指标偏差量计算出 HPA 所需的 target 值,驱动 Kubernetes 调整 Pod 副本数。
关键概念:Scaler 不直接操作 Pod,它只负责生成指标数据。KEDA Operator 将这些指标注入到 Kubernetes 自定义指标 API 中,HPA 再根据这些指标执行实际的扩缩容动作。
4.2 内置 Scaler 列表
KEDA 官方维护了 50+ 个内置 Scaler,覆盖了主流的消息中间件、数据库、监控系统和云服务。下表列出了生产环境中使用频率最高的 12 个 Scaler:
| Scaler 名称 | 事件源类型 | 典型指标 | 生产推荐度 |
|---|---|---|---|
| Kafka | 消息队列 | lag(消费者滞后量) | ★★★★★ |
| RabbitMQ | 消息队列 | queueLength(队列长度) | ★★★★★ |
| Prometheus | 监控系统 | 自定义 PromQL 查询结果 | ★★★★★ |
| AWS SQS | 云服务 | ApproximateNumberOfMessages | ★★★★☆ |
| Redis Lists | 缓存/队列 | listLength(列表长度) | ★★★★☆ |
| MySQL | 数据库 | 自定义 SQL 查询结果 | ★★★★☆ |
| PostgreSQL | 数据库 | 自定义 SQL 查询结果 | ★★★★☆ |
| Azure Service Bus | 云服务 | messageCount(消息数) | ★★★★☆ |
| GCP Pub/Sub | 云服务 | subscriptionSize(订阅积压量) | ★★★★☆ |
| HTTP | 网络请求 | 并发请求数 / 请求速率 | ★★★☆☆ |
| Cron | 时间调度 | 时间表达式匹配 | ★★★☆☆ |
| Elasticsearch | 搜索引擎 | 文档数量 / 查询负载 | ★★★☆☆ |
选型建议:消息队列类 Scaler(Kafka、RabbitMQ、SQS)是事件驱动架构的首选,因为它们能直接反映工作负载的积压情况。Prometheus Scaler 适合已有 Prometheus 监控体系且需要基于业务指标(如 QPS、错误率)做弹性伸缩的场景。
4.3 外部 Scaler 机制
当内置 Scaler 无法满足需求时,KEDA 提供了 外部 Scaler(External Scaler) 机制,允许用户通过 gRPC 协议自定义指标获取逻辑。外部 Scaler 是一个独立的 gRPC 服务,需要实现以下两个接口:
// 定义在 keda.sh/external-scaler 协议中
service ExternalScaler {
// 返回 Scaler 的元数据(名称、支持的指标等)
rpc GetMetricSpec(ScaledObjectRef) returns (MetricSpec);
// 返回当前指标值,KEDA 会按 pollingInterval 周期调用
rpc GetMetrics(MetricRequest) returns (MetricResult);
// 可选:检查 Scaler 是否健康
rpc IsActive(ScaledObjectRef) returns (IsActiveResult);
}
外部 Scaler 的工作流程如下:
- 用户编写一个 gRPC 服务,实现上述三个接口。
- 将该服务部署为 Kubernetes Deployment,并暴露 ClusterIP Service。
- 在 ScaledObject 中通过
external类型引用该 Service 地址。 - KEDA Operator 通过 gRPC 调用外部 Scaler 获取指标,其余流程与内置 Scaler 一致。
生产注意事项:外部 Scaler 的稳定性直接影响整个弹性伸缩链路。建议为外部 Scaler 服务配置独立的资源限制、健康检查和监控告警。gRPC 调用超时时间默认 5 秒,如果指标获取耗时较长,需要在 ScaledObject 中调整
pollingInterval 和 cooldownPeriod。
4.4 Scaler 的工作原理
Scaler 在 KEDA 中的完整工作周期包含四个阶段:注册 → 轮询 → 计算 → 反馈。下图展示了这一流程:
Scaler 在计算副本数时遵循以下公式:
期望副本数 = ceil( 当前指标值 / targetValue )
示例:
- Kafka 当前 lag = 1500
- targetValue = 500(每个 Pod 处理 500 条消息)
- 期望副本数 = ceil(1500 / 500) = 3 个 Pod
关键设计原则:Scaler 的计算结果始终是 向上取整 的整数,确保有足够的 Pod 处理积压。当指标值降为 0 时,Scaler 返回 0,HPA 会将副本数缩到 minReplicaCount(默认为 1)。如果希望缩到 0,需要启用
idleReplicaCount 特性。
4.5 Scaler 的配置示例
以下是一个使用 Kafka Scaler 的完整 ScaledObject 配置,展示了 Scaler 参数如何与工作原理对应:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kafka-consumer-scaler
namespace: production
spec:
scaleTargetRef:
name: kafka-consumer-deployment # 目标 Deployment
pollingInterval: 15 # 轮询间隔(秒),对应阶段 2
cooldownPeriod: 60 # 冷却时间(秒),防止频繁扩缩
minReplicaCount: 1 # 最小副本数
maxReplicaCount: 20 # 最大副本数
triggers:
- type: kafka
metadata:
bootstrapServers: kafka-cluster:9092
consumerGroup: my-consumer-group
topic: orders
lagThreshold: "100" # 触发扩容的滞后阈值
offsetResetPolicy: latest
# targetValue 默认 = lagThreshold,每个 Pod 处理 100 条消息
参数调优建议:
pollingInterval 不宜过短(建议 ≥10s),避免对事件源造成过大压力。cooldownPeriod 建议设置为指标采集周期的 2-3 倍,防止指标抖动导致频繁扩缩。