首页/数据/数仓建模速查/Spark 检查点与任务恢复
湖仓与引擎63 条

Spark 检查点与任务恢复

检查点把流状态与元数据落盘:流任务必须设置 checkpointLocation;批任务用本地检查点可以切断血缘过长的问题。

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

检查点解决什么

Spark 检查点把运行状态与血缘信息持久化到可靠存储。结构化流任务必须配置 checkpointLocation 才能记录处理进度与状态,故障重启后可续跑;批任务调用 checkpoint 则把 RDD 血缘截断,避免血统过长导致的重算与栈溢出。两者名称相同,作用与位置完全不同。

基本信息

流检查点记录 offset、状态、元数据,供重启续跑
批检查点setCheckpointDir 指定目录,配合 rdd.checkpoint 截断血缘
存储位置需要可靠共享存储,如 HDFS 或对象存储
版本兼容升级 Spark 大版本后旧检查点可能不兼容,需评估重建
清理流检查点需定期清理历史版本文件

典型使用场景

  • 流任务故障恢复:重启后从上次处理位置继续,避免重复消费
  • 带状态的流计算:窗口聚合、去重、自定义状态算子必须靠检查点保存状态
  • 批任务血缘过长:迭代计算或反复 union 后先 checkpoint 再触发计算
  • 任务迁移:集群或目录调整时评估检查点迁移方案
  • 调优与排障:通过检查点目录判断任务实际处理进度

批检查点用法

批检查点用法
// 指定可靠的检查点目录,集群模式下不能用本机临时目录
spark.sparkContext.setCheckpointDir("hdfs:///tmp/checkpoint")

// 先重分区再 checkpoint,避免产生大量小文件
val df = spark.table("dwd_trade_order_di").repartition(64).checkpoint()

df.count()   // checkpoint 是懒执行,必须触发一次 action 才会真正落盘

// 流任务:在 writeStream 上指定检查点位置,目录确定后不要随意更换
// .option("checkpointLocation", "hdfs:///user/dw/chk/order_stream")

检查点内容读法

内容含义异常表现
offsets已处理的数据位置缺失会导致任务从头或按起始配置重放
commits已提交的批次记录损坏会让任务无法判断断点,只能重建目录
state状态算子的中间结果丢失则状态归零,去重与聚合结果出错
metadata版本与查询配置信息与当前 Spark 版本不匹配时启动即失败
批检查点主要作用是切断血缘与复用中间结果,它把数据写到指定目录,会额外占用存储;只在一段计算会被多次引用或血统确实过长时才值得引入。
流任务的检查点目录一旦更换,等价于一个全新任务:要么重跑全部历史数据,要么从头开始消费,可能引发下游重复计算。目录要与业务数据分区存放,避免清理脚本误删。

易错点

  • 没配 checkpointLocation 就上线流任务,故障重启后按起始位置重放,下游出现重复数据
  • 批检查点目录写成 executor 本地临时目录,任务重跑或节点重启后目录消失,任务直接报错
  • 只设置检查点目录却从不触发 action,误以为已经落盘,重启时发现没有任何记录
  • 升级 Spark 大版本未评估检查点兼容性,任务启动失败且无法从旧目录恢复

数据来源与参考

  • Apache Spark 官方文档:Checkpointing
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌