订阅更新

Spark Structured Streaming 的 Append、Update 和 Complete 模式怎么选?

面试问 189 约 3 分钟读完

本文目录
  1. 面试怎么回答
  2. 先理解 Result Table
  3. Append 适合结果已经终结的记录
  4. Update 适合持续修正的结果
  5. Complete 会输出整张结果表
  6. 先选业务语义,再校验兼容矩阵
  7. 一个实用选择顺序
  8. 参考资料

面试怎么回答

Append 只输出以后不会再变化的新行,适合明细追加或 Watermark 后已关闭的窗口;Update 只输出本批更新行,适合实时修正,但 Sink 要支持按键覆盖或 Upsert;Complete 每批输出完整结果,只适合小结果集。选择时我会同时看业务是否需要最终值、状态是否可清理、Sink 能力和算子兼容性。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

流式聚合写文件时切到 Update 模式,作业可能直接报不支持;改成 Complete,又发现每个批次都在输出整张结果表。

Output Mode 不是性能开关,它定义的是每个 Trigger 要把结果表的哪一部分交给 Sink。

Append 只输出以后不会再变化的新行,Update 输出本批发生变化的行,Complete 输出完整结果表;选择必须同时满足计算语义、状态清理和 Sink 能力。

先理解 Result Table

Structured Streaming 把输入流持续更新为一张逻辑结果表。每个微批处理完,Output Mode 决定将这张表中的新增行、更新行还是全部行写给 Sink。它描述的是输出增量,不代表 Sink 自动具备更新或幂等能力。

Append 适合结果已经终结的记录

无状态明细通常可以直接追加。带窗口聚合时,只有 Watermark 超过窗口结束时间,Spark 才能认定该窗口不会再接收允许范围内的迟到数据,并在 Append 模式输出最终结果。优点是 Sink 简单,代价是结果出现得更晚。

三种 Output Mode 输出什么

Update 适合持续修正的结果

每个 Trigger 只输出本批发生变化的行,窗口未关闭前可以不断看到最新计数。Sink 必须能按业务键覆盖或幂等合并,否则相同窗口会留下多条版本。文件 Sink 通常不适合细粒度更新,而数据库、支持 Upsert 的表格式或 foreachBatch 更常见。

Complete 会输出整张结果表

每个 Trigger 都把当前完整结果重新写出,适合结果规模很小、Sink 支持整体替换或控制台调试。状态和输出规模随 Key 增长时,Complete 成本会迅速放大;在聚合场景中,它通常不会因为 Watermark 自动丢弃旧聚合状态。

Output Mode 的选择路径

先选业务语义,再校验兼容矩阵

要的是最终结果还是实时修正?Sink 能追加、覆盖还是 Upsert?状态能否被 Watermark 安全清理?同一个查询中的聚合、Join、去重对 Output Mode 有不同限制,提交前要用官方兼容表和小规模测试确认。

一个实用选择顺序

明细落湖优先 Append;需要持续更新仪表盘且 Sink 支持主键覆盖,考虑 Update;只有结果表很小且确实需要全量快照时才用 Complete。无论哪种模式,都要用 checkpoint 保证恢复,并在 Sink 端处理微批重试带来的幂等。

参考资料

刷题进度保存在当前浏览器