数仓中的迟到数据怎么处理?
面试怎么回答
我会先区分事件时间和到达时间,再按业务 SLA 定义窗口内迟到、窗口外可修正和超期异常。对可修正数据,根据事件时间定位受影响分区,以业务主键幂等回写,并沿血缘定向重算下游汇总。最后校验主键、行数和核心指标,记录修正批次,确保补数可追踪、可重试,不会因为重复到达再次算错。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
很多人第一反应是:
“把昨天的任务重跑一遍。”
重跑确实是一种补救手段,但它没有回答三个关键问题:数据到底迟到了多久、应该改写哪个业务日期、重复到达时会不会再次把指标算错。
迟到数据真正考验的不是调度系统会不会补跑,而是:
能不能把事件发生时间、数据到达时间和最终修正机制设计成一个可追踪的闭环。
第一步:先区分事件时间和到达时间
假设一笔订单 8 月 20 日完成,但上游接口到 8 月 22 日才把记录传过来:
- 事件时间是 8 月 20 日
- 到达时间是 8 月 22 日
- 处理时间可能是 8 月 22 日任务运行时
如果报表统计“8 月 20 日成交额”,这笔订单应该回到 8 月 20 日,而不是被算进 8 月 22 日。
所以设计表时,至少要保留业务事件时间和数据进入系统的时间。只保留分区日期,后面很难判断数据属于哪一天、迟到了多久。
第二步:明确可接受的迟到边界
不是所有数据都要无限期等待。
通常可以按业务 SLA 分三层:
窗口内迟到
例如 T+1 报表允许等待到次日 10 点。窗口关闭前到达的数据直接参与正常计算。
窗口外可修正
数据超过 SLA 才到,但仍在业务允许的回溯周期内。系统记录受影响的事件日期,并触发定向补算。
超期异常
超过最大回溯周期的数据不再静默改历史,而是进入异常队列,由数据和业务负责人确认是否修正。
边界越清楚,实时性、准确性和补算成本之间的取舍才越可控。
第三步:按事件日期定向修正

迟到数据在 8 月 22 日到达,不代表只重跑 8 月 22 日分区。
正确的修正流程通常是:
- 根据事件时间识别受影响的业务日期;
- 记录待修正分区和影响范围;
- 对目标明细表执行幂等写入;
- 从明细层向汇总层定向重算;
- 校验主键、行数和核心指标差异。
如果下游有日、周、月多级汇总,还要沿血缘找到所有受影响的结果,而不是只补最上游一张表。
第四步:保证补写和重跑幂等
迟到数据可能不只来一次,补数任务也可能失败重试。
常见做法包括:
- 以业务主键做
MERGE或覆盖更新 - 重算目标分区,而不是在旧结果上继续累加
- 保存修正批次、到达时间和处理状态
- 补算前后对主键重复、金额和记录数做核对
如果补数逻辑不是幂等的,同一批数据重跑两次,迟到问题就会变成重复问题。
一个典型场景
比如移动端埋点偶尔离线两天,恢复网络后才批量上报。
最初系统只按当天处理分区增量计算,8 月 20 日的事件在 8 月 22 日到达后,被写进 8 月 22 日统计,导致两天的活跃和转化都不准确。
只重跑 8 月 22 日无法修复 8 月 20 日。正确做法是保留事件日期,识别受影响分区,幂等回写 8 月 20 日明细,再定向刷新对应日、周汇总,并记录这次修正。
迟到数据不是“晚跑一次任务”,而是一次历史口径修正。