3. Spark Streaming 基础回顾:DStream 与 Structured Streaming 核心概念

在构建模型漂移巡查系统之前,必须扎实掌握 Spark Streaming 的两代核心 API。DStream(Discretized Stream)是 Spark Streaming 的原始抽象,而 Structured Streaming 是 Spark 2.x 之后主推的流计算引擎。理解两者的差异与适用场景,是设计实时漂移检测管线的第一步。

3.1 DStream:离散化流与微批次处理原理

DStream 将连续的数据流切分为一系列微小的 RDD 批次(Micro-Batch)。每个批次对应一个时间窗口内的数据,Spark 引擎以 RDD 批处理的方式执行计算,从而实现“准实时”处理。

核心原理: 数据流 → 时间切片(如 1s)→ 每个切片生成一个 RDD → 对 RDD 执行 Transformation 与 Action → 输出结果。
DStream 微批次处理流程 实时数据源 切片 1 RDD[0-1s] 切片 2 RDD[1-2s] 切片 3 RDD[2-3s] … 结果输出 关键特征: • 批次间隔(batchInterval)决定实时性:1s 批次延迟约 1-2s,适合秒级监控。 • 每个批次独立调度,容错通过 RDD lineage 实现。 • 状态管理依赖 updateStateByKey 或 mapWithState,需手动维护 checkpoint。

3.2 Structured Streaming:声明式流处理与增量执行

Structured Streaming 将流数据视为“无界表”(Unbounded Table),每到达一条记录即追加到表中。用户使用 DataFrame/Dataset API 编写批处理风格的查询,引擎自动将其转换为增量执行计划(Incremental Execution Plan)。

对比维度 DStream Structured Streaming
编程抽象 RDD 级别的离散化流 DataFrame/Dataset 无界表
处理语义 At-Least-Once(需手动去重) Exactly-Once(内置端到端一致性)
状态管理 updateStateByKey / mapWithState 内置 State Store + watermark
延迟 依赖 batchInterval,通常 1s+ 支持连续处理模式(1ms 级)
容错恢复 基于 checkpoint + WAL 基于 offset + State Store + WAL
适用场景 遗留系统、自定义算子需求 新项目、SQL 化、与批处理统一
实战建议: 模型漂移巡查推荐使用 Structured Streaming。其内置的 watermark 机制可以自动处理乱序数据,State Store 支持大规模状态管理,非常适合长时间运行的漂移检测任务。

3.3 窗口操作与状态管理

窗口操作是流计算中处理时间序列数据的核心手段。模型漂移检测通常需要观察一段时间内的统计特征变化,因此必须掌握滑动窗口(Sliding Window)与滚动窗口(Tumbling Window)的配置方法。

3.3.1 窗口类型与参数

窗口类型 窗口长度 滑动步长 数据重叠 典型用途
滚动窗口 固定(如 10min) 等于窗口长度 无 按固定周期统计模型指标
滑动窗口 固定(如 10min) 小于窗口长度(如 2min) 有 实时监测漂移趋势变化
会话窗口 动态(由不活跃间隔决定) 不适用 按会话合并 用户行为序列漂移检测

3.3.2 状态管理机制

Structured Streaming 的状态管理通过 State Store 实现,支持大规模、高可靠的状态维护。在模型漂移场景中,状态通常用于存储历史统计量(如均值、方差、分位数),以便与当前窗口数据对比。

// Structured Streaming 窗口聚合 + 状态管理示例
import spark.implicits._

val streamDF = spark.readStream
  .format("kafka")
  .option("kafka.bootstrap.servers", "localhost:9092")
  .option("subscribe", "model-predictions")
  .load()
  .selectExpr("CAST(value AS STRING) as json")
  .select(from_json($"json", schema).as("data"))
  .select($"data.model_id", $"data.prediction", $"data.timestamp")

// 滑动窗口:每 2 分钟统计过去 10 分钟的预测分布
val windowedStats = streamDF
  .withWatermark("timestamp", "5 minutes")
  .groupBy(
    $"model_id",
    window($"timestamp", "10 minutes", "2 minutes")
  )
  .agg(
    avg($"prediction").as("avg_pred"),
    stddev($"prediction").as("std_pred"),
    count($"prediction").as("sample_count")
  )

// 输出到控制台(调试用)
windowedStats.writeStream
  .outputMode("update")
  .format("console")
  .option("truncate", "false")
  .start()
  .awaitTermination()
避坑提示:
  • 窗口长度不宜过短(< 1min),否则状态更新频繁,State Store 压力大。
  • watermark 延迟设置需大于最大乱序时间,否则会丢弃有效数据。
  • outputMode 选择 "update" 或 "append":漂移检测通常用 "update" 模式输出最新状态。

3.4 微批次执行引擎的容错与一致性

无论是 DStream 还是 Structured Streaming,底层都依赖微批次执行引擎。理解其容错机制有助于设计高可靠的漂移检测管线。

Structured Streaming 容错架构 Kafka / 数据源 Offset 管理 记录已消费偏移量 微批次执行 增量处理 + 状态更新 State Store HDFS / RocksDB 容错恢复流程: 1. 任务失败 → 从 checkpoint 读取上次成功提交的 offset。 2. 重新拉取数据 → 从 State Store 恢复中间状态 → 重新执行微批次。 3. 输出结果 → 提交 offset → 保证 Exactly-Once 语义。

3.5 本章小结

  • DStream 适合需要细粒度 RDD 控制的场景,但状态管理较复杂。
  • Structured Streaming 是模型漂移巡查的首选方案,提供声明式 API、内置状态管理和 Exactly-Once 语义。
  • 窗口操作 是漂移检测的基础,滑动窗口适合连续监测,滚动窗口适合定期统计。
  • 状态管理 依赖 State Store,合理设置 watermark 和 checkpoint 间隔是生产稳定运行的关键。
下一阶段: 掌握这些基础后,第 4 章将进入模型漂移检测的核心——统计检验方法与实时特征对比策略。