幂等重跑是什么
幂等的含义是「同一任务跑一次和跑十次,结果一样」。这在数据管道里不是可选项:上游补数、口径调整、任务失败重试都会触发重复运行,如果任务自带累加逻辑,重跑就等于把数据翻倍。最稳妥的实现方式是输出按分区覆盖写,其次是按主键 upsert,再次是写临时表后原子切换;最危险的是依赖上次运行状态的累加(+=、count++ 之类)。
基本信息
| 首选方案 | 输出按分区覆盖(INSERT OVERWRITE PARTITION) |
|---|---|
| 次选方案 | 按主键 upsert / MERGE |
| 兜底方案 | 写临时表后切换或改名 |
| 应避免 | 依赖上次运行状态的累加逻辑 |
| 前置条件 | 输出表有明确的分区键或主键 |
| 配套要求 | 重跑范围可界定、可观测、可回滚 |
分区覆盖重跑
分区覆盖重跑
-- 重跑 2026-10-11 分区:先写该分区,覆盖旧结果
INSERT OVERWRITE TABLE ads_sales_daily PARTITION (dt = '2026-10-11')
SELECT dt, channel, SUM(amount)
FROM dwd_order WHERE dt = '2026-10-11'
GROUP BY dt, channel;典型使用场景
- 上游断数后补数:只重跑受影响分区,结果与首次运行一致
- 口径变更重刷:历史区间按新逻辑覆盖,不残留旧口径数据
- 失败重试:调度器自动重试时不会产生重复数据
- 跨天累计指标:改用「按天快照 + 查询时累加」,避免在表里维护累计值
- 消息消费:下游按主键 upsert,重复投递不会产生重复行
写入方式对照
| 方式 | 幂等性 | 注意 |
|---|---|---|
| 分区覆盖写 | 好 | 必须带分区条件,防止误删历史 |
| 主键 upsert | 好 | 主键取值要稳定唯一 |
| 拼接追加 | 差 | 重跑必然产生重复 |
| 读旧值再加 | 差 | 并发与重跑都会放大误差 |
| 写临时表再切换 | 好 | 切换动作本身要原子 |
重跑前先确认输出分区不会被其他并发任务覆盖;跨任务写同一分区时加调度依赖或互斥。
所谓「临时表 + 切换」在对象存储上不是原子操作:改名可能退化成拷贝,切换期间会出现半成品数据被读到,需要下游按目录版本或元数据指针读取。