幂等设计
总结
| 记忆点 | 内容 |
|---|---|
| 幂等定义 | 跑一次和跑N次,结果一样 |
| 第一铁律 | 离线任务用INSERT OVERWRITE,禁INSERT INTO |
| 分区表 | OVERWRITE指定分区,最简单最标准 |
| 全量表 | 全表OVERWRITE或临时表RENAME |
| 累积表 | FULL JOIN + COALESCE合并 |
| 实时表 | 利用OLAP引擎主键模型去重 |
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
进阶 | 大数据面试 · 数仓建模系列
| 面试真题 你们的数仓任务是怎么保证幂等性的?任务重跑会不会产生重复数据? |
|---|
什么是幂等?
一个操作执行一次和执行N次,结果完全一样,就叫幂等。对数仓来说:同一个任务重跑一遍或跑十遍,最终数据都一样,不会多也不会少。生产环境中任务失败重跑是家常便饭——上游延迟了、集群抖了、OOM了——重跑时如果数据翻倍,那就是生产事故。
| Wood的实战经验 我刚入行时就犯过这个错。一个写入任务用了INSERT INTO(追加写入),任务失败后自动重试了3次,结果同一批数据写了4遍,当天的GMV直接翻了4倍。老板看报表发现GMV暴涨开心了5分钟,然后数据团队就被叫去开会了。从那以后,我所有的离线任务都用INSERT OVERWRITE。 |
|---|
离线数仓幂等的核心:INSERT OVERWRITE
INSERT INTO = 追加模式,重跑会重复。INSERT OVERWRITE = 先删再写,不管跑几次结果都一样。这是离线数仓幂等设计的第一铁律。
| -- ✖ INSERT INTO:追加模式,重跑会重复 INSERT INTO TABLE fact_order PARTITION(dt='2025-01-15') SELECT * FROM ods_order WHERE dt='2025-01-15'; -- 跑第一次:100万行,重跑:200万行(重复了!) -- ✔ INSERT OVERWRITE:覆盖模式,重跑结果不变 INSERT OVERWRITE TABLE fact_order PARTITION(dt='2025-01-15') SELECT * FROM ods_order WHERE dt='2025-01-15'; -- 跑第一次:100万行,重跑:还是100万行 ✔ |
|---|
不同场景的幂等方案
分区表(最简单):INSERT OVERWRITE指定分区,只影响当天分区,其他分区不受影响。最标准最推荐。
全量表(无分区):全表OVERWRITE也是幂等的。但执行过程中表是空的(先删后写),优化方案是写临时表→RENAME替换,实现原子操作。
累积快照型:FULL OUTER JOIN + COALESCE合并新旧数据,整个分区重写,天然幂等。
实时写入:Flink写Doris/Hologres时靠主键去重。Doris的Unique模型写入相同主键自动覆盖旧值,天然幂等。
幂等设计Checklist
| 检查项 | 要求 |
|---|---|
| 写入方式 | INSERT OVERWRITE,禁止INSERT INTO |
| 分区指定 | 明确指定目标分区 |
| 数据范围 | SELECT的WHERE和目标分区对齐 |
| 累积表 | FULL JOIN + COALESCE合并 |
| 实时表 | 利用主键模型做去重 |
| 验证 | 跑两次,对比行数和关键指标必须一致 |
| 面试加分提示 「我们所有离线任务都用INSERT OVERWRITE+分区指定来保证幂等。这是入职第一天就会告诉新人的规范。我之前踩过坑——INSERT INTO导致数据翻4倍。从那以后Code Review重点检查写入方式,每个任务上线前都跑两次验证幂等性。累积快照型用FULL JOIN+COALESCE做merge逻辑,同样保证重跑不重复。」 关键:规范+踩坑故事+预防机制。 |
|---|