CodeWalk

Structured Streaming与Exactly-Once语义

作者:小字辈 · 2026-05-30 12:55

请介绍Structured Streaming的工作原理及其如何实现Exactly-Once语义。

回答

小字辈

Structured Streaming定义: Spark 2.x引入的流处理引擎,基于DataFrame/Dataset API,支持端到端的Exactly-Once语义。

核心思想:

  • 将源源不断的数据流视为无限增长的输入表(Unbounded Table)
  • 每个批次的数据被追加到输入表中
  • 对输入表执行SQL查询,产生结果表(Result Table)
  • 结果表按Trigger间隔输出到外部系统

三种输出模式:

  1. Complete Mode: 每次写出完整的结果表(适合聚合查询)
  2. Append Mode: 只写出新增的行(适合过滤器/投影)
  3. Update Mode: 只写出更新的行(支持聚合更新)

Exactly-Once实现机制:

1. 端到端Exactly-Once = 幂等写入 + 可重放源 + 检查点:

2. 源可重放:

  • Kafka的offset保存在Checkpoint中
  • 失败重启后从Checkpoint记录的offset重新消费

3. Checkpoint机制:

  • 记录每个批次处理的offset范围处理状态
  • 存储在可靠文件系统(HDFS/S3)
  • 恢复时精确恢复上次的状态和offset

4. 幂等写入(Idempotent Sink):

  • 将批次ID写入Sink(如HBase rowKey含批次ID)
  • 同一个批次重复写入时自动去重

5. 状态管理(State Store):

  • 使用HDFSBackedStateStoreProvider存储聚合状态
  • 启用WAL(Write Ahead Log)保证状态不丢失

配置:

val df = spark.readStream
  .format("kafka")
  .option("startingOffsets", "earliest")
  .option("failOnDataLoss", "false")
  .load()
  .writeStream
  .outputMode("append")
  .format("parquet")
  .option("checkpointLocation", "/checkpoint")
  .trigger(Trigger.ProcessingTime("10 seconds"))
  .start()