回补与重放是什么
回补(backfill)是把某个历史时间段的数据重新计算并写出,或在目标端重放变更。它是同步链路的常规操作:故障、口径调整、上游修复后都需要。设计要点四句话——幂等(重跑结果与执行一次相同)、限速(不压垮源与目标)、可观测(进度与差异可核对)、可中断续跑(大回补拆批并记录进度)。缺任何一项,回补本身就会变成一次新的故障。
基本信息
| 幂等手段 | 分区覆盖写、按主键 upsert、先删后写 |
|---|---|
| 执行顺序 | 先回补历史再让增量追平,或显式冻结该时段写入 |
| 限速方式 | 拆批 + 并发上限,按对源库与目标端的压力预算设定 |
| 进度记录 | 每批记录已完成的键范围或分区,可中断后从断点续跑 |
| 验收方式 | 行数与校验和比对,并记录回补批次、执行人与原因 |
典型使用场景
- 链路中断恢复:增量断了几小时,需补齐缺失区间并确认无空洞
- 口径变更重算:指标定义调整后按历史区间重跑
- 上游修数后追平:源端修正了错误数据,目标端同步重放
- 新表初始化:新模型上线时用回补方式补齐历史分区
- 应急修正:单条或单批数据算错,按主键定向重写
幂等回补(分区覆盖写)
幂等回补(分区覆盖写)
-- 目标端按分区覆盖重写:重跑多次结果一致,可安全重试
INSERT OVERWRITE TABLE dwd_trade_order_di PARTITION (dt = '2026-10-10')
SELECT order_id, user_id, pay_amount, status, update_time
FROM ods_trade_order_change_log
WHERE dt = '2026-10-10'
AND op <> 'd'; -- 墓碑行不保留,删除在目标端另行处理
-- 写入后立即校验分区行数,与预期区间对比
SELECT COUNT(1) AS cnt, MIN(update_time) AS min_t, MAX(update_time) AS max_t
FROM dwd_trade_order_di WHERE dt = '2026-10-10';分批与限速执行
分批与限速执行
# 按天逐批回补,批间留间隔;每批完成即记录进度,可中断续跑
for d in $(seq -w 1 10); do
echo "backfill dt=2026-10-${d} start"
hive -e "INSERT OVERWRITE TABLE dwd_trade_order_di PARTITION (dt='2026-10-${d}') SELECT ..."
echo "backfill dt=2026-10-${d} done"
done
# Airflow 2.x 触发历史区间(1.x 的 airflow backfill 命令已移除)
airflow dags backfill daily_orders --start-date 2026-10-01 --end-date 2026-10-10回补设计检查项
| 检查项 | 要求 | 不满足的后果 |
|---|---|---|
| 幂等 | 重跑结果与执行一次一致 | 重跑一次数据翻倍,越修越乱 |
| 顺序 | 回补与增量不并发写同一分区 | 结果不可预期,差异无法对账 |
| 限速 | 拆批并设并发上限 | 跨库拉数拖慢源库,影响在线业务 |
| 可续跑 | 记录批次与断点 | 中断后只能从头再来,反复占用资源 |
| 验收 | 行数与校验和比对并留痕 | 无法证明问题已修复 |
回补与增量同时写同一分区会造成结果不可预期:先明确冻结哪一段、按什么顺序执行,并在回补期间暂停对应区间的调度。