首页/数据/数仓建模速查/Structured Streaming:微批与输出模式
湖仓与引擎63 条

Structured Streaming:微批与输出模式

Structured Streaming 以微批或连续模式处理流数据,输出模式 append/update/complete 决定结果写入语义,配合 watermark 处理迟到数据。

数仓建模速查数据更新于 2026-10-13

Structured Streaming 的工作方式

Structured Streaming 把流数据当成一张不断追加的表,用与批处理相同的 API 写逻辑,引擎按微批执行。输出模式决定结果如何写入下游:是只追加新增行,还是持续更新已有行。迟到数据靠 watermark 划定等待边界,超出的部分按策略丢弃或交给离线链路兜底。

基本信息

执行方式微批为主,也有连续处理模式
输出模式append / update / complete
迟到处理watermark 划定等待水位
落点文件、表、或 forEachBatch 自定义
检查点checkpointLocation,必需用于故障恢复

典型使用场景

  • 准实时落仓:Kafka 事件流按分钟微批落到湖表分区
  • 实时聚合:按维度做分钟级汇总,结果表持续更新
  • 流批一体:同一套逻辑先用流跑当天,再用批回刷历史
  • 多落点写入:forEachBatch 里同时写明细与聚合结果
  • 与离线对齐:流任务产出当天明细,离线任务次日重跑同一分区口径

微批写入示例

微批写入示例
q = (spark.readStream.format('kafka')
     .option('kafka.bootstrap.servers', 'broker:9092')
     .option('subscribe', 'trade_events')
     .load()
     .writeStream.format('parquet')
     .option('checkpointLocation', '/ck/stream_trade')  # 必需:断点续跑
     .option('path', '/warehouse/stream/trade')
     .trigger(processingTime='1 minute')
     .outputMode('append')
     .start())

输出模式对照

模式写入行为适用查询
append只写新增行无聚合或带 watermark 的聚合
update只写有变化的行带聚合需持续更新结果
complete重写整张结果表结果集很小的聚合统计
forEachBatch自定义每次微批的写出需写多个落点或做幂等控制
watermark 的等待时长要与业务容忍度对齐:设得太短会丢掉可用的迟到数据,设得太长则状态持续占用内存,检查点体积随之增大。
没有 checkpointLocation 的流任务无法恢复进度,重启后会从最早的偏移重新消费,产出重复数据且难以事后去重。

流与离线的口径怎么对齐

常见做法是让流任务只负责及时性,离线任务在次日重跑同一天分区,用离线结果覆盖流结果。这样既能满足小时级的看数需求,又能保证最终口径与批处理一致。前提是两套逻辑使用同一份 SQL 或同一个视图定义,避免两边各写一份。

上线前检查项

  • 确认检查点目录在共享存储上,且不会被清理任务误删
  • 确认输出模式与查询类型匹配,聚合查询不要直接配 append
  • 明确迟到数据的处置路径:丢弃、修正批次还是交给离线回刷
  • 压测单批处理时长,确保小于触发间隔以避免持续堆积
  • 记录消费起始偏移,方便事故后按偏移重放

易错点

  • 流任务未设置检查点目录,重启后数据重复
  • 把 append 模式用在无 watermark 的聚合查询上,引擎报错或结果迟迟不输出
  • 持续扩大 watermark 等待时长,状态体积膨胀导致检查点超时
  • 流与离线同时写同一分区,互相覆盖,产出结果难以复现

数据来源与参考

  • Apache Spark 官方文档:Structured Streaming
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌