数据回填与重放设计 是做什么的?
适用场景
- 为新模型/管道加载历史数据。
- 修复转换bug后重新处理过去的时间窗口。
- 重放事件或从原始数据重新派生表。
- 请勿用于正常增量运行(请使用
building-dbt-models/authoring-airflow-dags)。
为何需要谨慎对待
回填是数据工程中最危险的常规操作:它会重写历史数据。操作不当会导致重复计数、改变昨日数据或使生产过载。操作得当则枯燥且可重复。前提条件是幂等性(参见 writing-idempotent-transformations)。
工作流程
- [ ] 回填前确认转换是幂等的(重新运行 == 运行一次)
- [ ] 定义精确的时间窗口和分区粒度
- [ ] 对一个分区进行试运行;对比源数据验证计数/总和
- [ ] 按分区执行(有限并行),而非一次性全部运行
- [ ] 将回填计算与生产工作负载隔离
- [ ] 验证总计并核对;然后恢复正常调度
- 先证明幂等性。 如果重新运行某个窗口会改变结果,在触碰历史数据前先修复这个问题。回填非幂等作业会导致数据成倍增加。
- 精确界定范围。 确切的开始/结束时间以及分区单元(天/小时/区域)。
- 对一个分区进行试运行 并在扩展前与源数据进行核对。
- 分块运行。 以限制的批处理方式处理分区,以便监控、暂停和恢复——切勿一次性提交一个巨大无界的作业。
- 隔离计算资源。 使用单独的仓库/集群/池,避免回填抢占生产SLA。
- 验证并恢复。 在回填范围内核对总计,然后交回正常调度。
模式
幂等按分区回填 —— 每个分区覆盖是独立的,且可安全重试:
# 有限并行,一次一天;每天覆盖其自己的分区。
for day in $(seq_dates 2026-01-01 2026-01-31); do
run_transform --run-date "$day" # 仅针对该天执行 delete-insert / MERGE
done
Airflow —— catchup/backfill 重新运行数据间隔;仅当任务幂等且以数据间隔作为参数时才安全。 dbt —— 将增量模型过滤到目标窗口,或对有限窗口使用 --full-refresh。
隔离 + 限流 —— 专用仓库/集群及并发上限,确保回填不会降低实时仪表盘的性能。
常见陷阱
- 回填非幂等作业 —— 导致重复或偏移的总计数据;先使其幂等。
- 一次性无界运行 —— 无法监控或恢复,且会压垮生产环境;坚持按分区执行。
- 共享生产计算资源 —— 回填负载激增并破坏SLA;请隔离。
- 不进行验证 —— 假设成功;在范围内核对计数/总和。
- 中途更改逻辑 —— 导致历史不一致;在整个运行过程中固定代码版本。
- 忘记下游依赖 —— 回填基础表而不刷新依赖的集市/聚合,会导致数据不一致。