4. ScaledJob详解:ScaledJob CRD定义、Job触发策略、Job执行模式、Job清理策略

ScaledJob 是 KEDA 中专门用于管理 批处理任务(Job) 弹性伸缩的核心 CRD。与 ScaledObject 管理 Deployment/StatefulSet 这类长期运行服务不同,ScaledJob 负责根据事件源指标动态创建 Kubernetes Job 对象,并在任务完成后自动清理。本章将深入解析 ScaledJob 的 CRD 定义、触发策略、执行模式与清理策略。

4.1 ScaledJob CRD 定义

ScaledJob 的 CRD 定义在 keda.sh API 组下,版本为 v1alpha1。其核心结构包含 spec 和 status 两部分,其中 spec 定义了任务模板、触发器和伸缩策略。

字段 类型 说明
jobTargetRef batchv1.JobSpec 标准 Kubernetes Job 模板,定义容器镜像、命令、资源限制等
triggers []ScaleTrigger 事件源触发器列表,支持 Prometheus、Kafka、RabbitMQ 等
scalingStrategy ScalingStrategy 伸缩策略,定义 Job 执行模式与并发控制
successfulJobsHistoryLimit int32 保留的成功 Job 历史数量,默认 5
failedJobsHistoryLimit int32 保留的失败 Job 历史数量,默认 5
pollingInterval int32 轮询事件源指标的间隔(秒),默认 30
cooldownPeriod int32 缩容冷却期(秒),默认 300
maxReplicaCount int32 最大并行 Job 数量,默认 100
关键区别: ScaledJob 的 jobTargetRef 直接引用 batch/v1.JobSpec,而非像 ScaledObject 那样引用 Deployment。这意味着 ScaledJob 不管理 Pod 的生命周期,而是管理 Job 对象的创建与清理。

4.2 Job 触发策略

ScaledJob 的触发策略决定了 何时 以及 创建多少个 Job 实例。触发策略由 triggers 字段定义,每个触发器包含类型、元数据和认证引用。

4.2.1 触发器类型

触发器类型 典型场景 指标示例
prometheus 基于监控指标触发批处理任务 队列深度 > 100
kafka Kafka 分区未消费消息数 lag > 50
rabbitmq RabbitMQ 队列消息数 queueLength > 10
azure-queue Azure Storage Queue 消息数 queueLength > 0
cron 定时触发批处理任务 cron 表达式

4.2.2 触发计算逻辑

KEDA 根据触发器返回的指标值,通过以下公式计算期望的 Job 数量:

desiredJobs = ceil(metricValue / threshold)

例如,当 Kafka 分区 lag 为 250,阈值设为 100 时,KEDA 会创建 ceil(250/100) = 3 个 Job 并行处理。

最佳实践: 对于消息队列类触发器,建议将 threshold 设置为单个 Job 能高效处理的消息数量,避免创建过多小 Job 导致调度开销过大。

4.3 Job 执行模式

ScaledJob 支持两种执行模式,通过 scalingStrategy 字段控制:默认模式 和 自定义伸缩模式。

4.3.1 默认模式

在默认模式下,KEDA 根据触发器指标直接计算并创建对应数量的 Job。每个 Job 独立运行,互不干扰。适用于无状态、可并行处理的批处理任务。

4.3.2 自定义伸缩模式

自定义模式通过 scalingStrategy 的 strategy 字段指定,支持以下策略:

策略名称 说明 适用场景
default 直接根据指标创建 Job,无额外限制 简单并行任务
custom 通过 multipleScalersCalculation 自定义计算逻辑 多指标加权、优先级队列
accurate 精确模式,确保每个 Job 处理固定数量的工作单元 需要精确分配任务的场景
示例: 使用 accurate 模式时,可以设置 targetMetricValue 为每个 Job 处理 10 条消息,KEDA 会确保每个 Job 只处理 10 条,避免重复处理。

4.4 Job 清理策略

ScaledJob 提供了自动清理机制,防止历史 Job 对象堆积。清理策略通过以下参数控制:

  • successfulJobsHistoryLimit:保留最近 N 个成功完成的 Job,超出部分自动删除。默认值 5,设置为 0 表示不保留。
  • failedJobsHistoryLimit:保留最近 N 个失败的 Job,超出部分自动删除。默认值 5,设置为 0 表示不保留。

清理操作由 KEDA Operator 在每次伸缩循环中执行,确保集群资源不会因历史 Job 对象而耗尽。

注意: 清理策略仅删除 Job 对象本身,不会删除 Job 创建的 Pod 日志或持久化数据。如果需要保留日志,建议配置外部日志收集系统(如 Loki、Elasticsearch)。

4.5 ScaledJob 完整工作流程

下图展示了 ScaledJob 从指标采集到 Job 创建、执行、清理的完整生命周期:

ScaledJob 工作流程 事件源(Kafka/Prometheus) KEDA Operator 计算期望 Job 数量 创建 Kubernetes Job Job 执行与完成 清理历史 Job 对象 触发策略 指标值 / 阈值 = 期望Job数 maxReplicaCount 限制上限 执行模式 default / custom / accurate 支持多指标加权计算 清理策略 successfulJobsHistoryLimit failedJobsHistoryLimit

4.6 实战示例:基于 Kafka 的 ScaledJob 配置

以下是一个完整的 ScaledJob YAML 示例,展示如何配置 Kafka 触发器、自定义伸缩策略和清理策略:

apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
  name: kafka-consumer-job
spec:
  jobTargetRef:
    template:
      spec:
        containers:
        - name: consumer
          image: myregistry/consumer:latest
          command: ["/bin/sh", "-c", "process-messages.sh"]
          resources:
            limits:
              cpu: "1"
              memory: "512Mi"
        restartPolicy: Never
    backoffLimit: 3
  triggers:
  - type: kafka
    metadata:
      bootstrapServers: kafka-cluster:9092
      topic: orders
      consumerGroup: keda-consumer
      lagThreshold: "100"
  scalingStrategy:
    strategy: accurate
    targetMetricValue: "10"
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 2
  maxReplicaCount: 20
  pollingInterval: 15
  cooldownPeriod: 60
关键配置解读:
  • lagThreshold: "100":当 Kafka 分区滞后超过 100 条消息时触发伸缩。
  • strategy: accurate + targetMetricValue: "10":每个 Job 精确处理 10 条消息,避免重复消费。
  • successfulJobsHistoryLimit: 3:只保留最近 3 个成功的 Job,减少 etcd 存储压力。

4.7 避坑指南

  • Job 幂等性:ScaledJob 可能因网络抖动或 Operator 重启导致重复创建 Job,务必确保 Job 内的业务逻辑是幂等的。
  • 资源配额:maxReplicaCount 设置过高可能导致集群资源耗尽,建议结合集群节点资源进行合理限制。
  • 清理策略与日志:清理策略不会删除 Pod 日志,如需持久化日志,应在 Job 内配置日志输出到外部存储。
  • 触发器阈值:阈值设置过小会导致频繁创建小 Job,增加调度开销;设置过大则可能导致任务积压。建议根据单个 Job 的处理能力进行调优。