CodeWalk

Spark Structured Streaming窗口聚合详解

作者:专业代码师 · 2026-05-30 12:55

Spark Structured Streaming支持哪些窗口聚合类型?请详细说明滚动窗口(Tumbling Window)、滑动窗口(Sliding Window)、会话窗口(Session Window)的实现原理、语法和适用场景。如何处理窗口聚合中的乱序数据和迟到数据?

回答

专业代码师

1. 窗口类型

滚动窗口(Tumbling Window)

df.groupBy(
  window($"event_time", "10 minutes"),
  $"device_id"
).count()
  • 固定大小,不重叠
  • 适合:每分钟PV统计

滑动窗口(Sliding Window)

df.groupBy(
  window($"event_time", "10 minutes", "5 minutes"),
  $"device_id"
).count()
  • 大小=10min,滑动步长=5min
  • 每条数据出现在2个窗口中
  • 适合:实时监控趋势

会话窗口(Session Window)

import org.apache.spark.sql.streaming._
df.groupBy(
  session_window($"event_time", "5 minutes"),
  $"user_id"
).count()
  • 基于活动间隔(gap)拆分
  • 超过gap无活动则结束会话
  • 适合:用户行为分析

2. 乱序与迟到数据处理

// Watermark设置
.withWatermark("event_time", "10 minutes")
// 允许最多10分钟的乱序

// 输出模式
// Append模式:窗口关闭后输出结果
// Update模式:每次更新输出最新结果

晚到数据策略

  • 丢弃:超过Watermark的数据被丢弃
  • 延迟触发withWatermark设定容忍时间
  • 部分更新:如果在窗口范围内,重新计算并更新结果

3. 聚合优化

// 避免数据倾斜
// 使用salt技术
.groupBy($"key", $"salt").agg(...)

// 配置优化
spark.conf.set("spark.sql.streaming.stateStore.stateSchemaCheck", "false")

4. 适用场景对比

窗口类型延迟要求数据量典型场景
Tumbling严格每分钟PV/UV
Sliding中等滑动平均/趋势
Session宽松用户会话/点击流