3. 数据回补核心概念

在风控数据链路中,数据缺失、延迟、错乱几乎是常态。无论是上游业务系统故障、消息队列积压、离线任务失败,还是规则变更导致历史数据口径不一致,都会让风控决策所依赖的数据出现“空洞”。数据回补就是针对这些空洞进行系统性修复的工程动作。理解回补,必须先把它和日常说的“补数”区分开,否则很容易在方案设计时把两类问题混为一谈。

一、回补的定义:面向时间窗口的批量修复

数据回补(Backfill)是指:当某个历史时间段内的数据出现缺失、错误或不完整时,按照原始业务时间语义,重新计算或重新导入该时间段的数据,使其恢复到“如果当时链路正常就应该产生的结果”。回补的核心特征有三个:

  • 面向历史时间窗口:回补总是针对一个明确的时间区间,例如“2024-06-01 00:00 至 2024-06-01 23:59”。
  • 保持业务时间语义:回补后的数据必须落在它原本应该归属的业务日期或事件时间上,而不是写入时间。
  • 结果可审计:每一次回补都要有记录,包括回补范围、触发原因、执行人、影响行数、校验结果。

从工程视角看,回补不是简单的“把数据重新跑一遍”,而是要在幂等性、顺序性、一致性三个约束下完成修复。如果回补任务不具备幂等性,重复执行就会产生重复数据;如果回补打乱了事件顺序,风控规则中的滑动窗口、累计计数就会失真。

二、回补与补数的区别:目标不同,手段不同

“补数”在日常沟通中常被泛化使用,但在严谨的风控数据体系里,它和回补有明确边界。补数更偏向点状修复:某条记录错了、某个字段空了、某个用户标签丢了,针对具体记录做修正。回补则是面状修复:整个时间分区、整个业务链路的结果需要重算。

对比维度 数据回补 补数
修复对象 历史时间窗口内的批量数据 单条或少量异常记录
触发原因 任务失败、链路中断、口径变更 字段缺失、值错误、关联丢失
执行方式 重跑离线任务或重放消息 定向更新、手工修正、小批量导入
影响范围 通常影响多个下游表与指标 影响范围局部且可控
审计要求 高,需记录窗口、版本、校验 中,需记录修改前后值
典型风险 重复计算、口径漂移、下游连锁 遗漏关联、覆盖新值
判断标准:如果修复动作需要“按时间分区重算”,就是回补;如果只是“把某条记录改对”,就是补数。两者可以同时发生,但方案和审批流程应分开设计。

三、回补的触发条件:什么时候必须回补

回补不是随时可做的操作,它需要明确的触发条件。常见触发场景包括:

  1. 离线任务失败:例如风控日终跑批任务因资源不足或代码异常失败,导致某天分区为空。
  2. 消息队列积压或丢失:实时链路中 Kafka 分区不可用,部分事件未写入明细表。
  3. 上游数据延迟到达:业务系统 T+1 才补推前一天的数据,导致实时风控当时使用了不完整数据。
  4. 规则或口径变更:风控策略调整后,需要按新口径重算历史指标以保持一致性。
  5. 数据质量校验不通过:例如某天逾期率异常偏低,排查发现部分还款事件未入仓。

触发之后,不能立即执行回补,而要先做影响面评估:哪些下游表依赖该分区?哪些指标看板会变化?是否有正在运行的实时任务会与回补数据冲突?评估完成后,再选择回补方式。常见方式有两种:

# 方式一:按分区重跑离线任务
spark-submit \
  --class com.risk.BackfillJob \
  --conf spark.app.name=risk_backfill_20240601 \
  --conf spark.risk.bizDate=2024-06-01 \
  --conf spark.risk.mode=backfill \
  risk-backfill.jar

# 方式二:重放消息队列中的历史事件
kafka-consumer-groups.sh \
  --bootstrap-server broker:9092 \
  --group risk-replay-group \
  --topic risk_event \
  --reset-offsets --to-datetime 2024-06-01T00:00:00.000 \
  --execute

无论哪种方式,都必须保证幂等写入。例如在 Hive 或数仓中采用“先删分区再写入”或“覆盖写”模式,避免同一业务日期出现两份数据。

四、业务场景与风险:回补不是免费的

在风控领域,回补最典型的场景是贷后指标重算。假设某天因为上游还款系统故障,部分还款成功事件没有进入风控明细表,导致当天的逾期率被高估。第二天发现后,需要回补该天的还款事件,并重新计算逾期率、滚动率、迁徙率等指标。如果回补不彻底,管理层看到的报表就是错的,可能引发错误的策略调整。

另一个场景是实时风控特征回补。实时决策时使用了用户近 30 天借款次数,但其中某几天的借款事件丢失。回补后,这些用户的特征值会发生变化,历史决策结果也需要重新评估。此时要注意:回补的是特征数据,不是决策结果。决策结果一旦产生,通常不直接修改,而是通过“决策重放”来验证新特征下的结果差异。

回补的三大风险:第一,重复计算——回补任务非幂等,导致数据翻倍;第二,口径漂移——回补时使用了与原始任务不同的代码版本或参数,导致历史数据与当前数据不可比;第三,下游连锁——回补了明细表,但下游汇总表、特征表、报表没有同步重算,造成数据不一致。

为了控制风险,建议建立回补清单制度。每次回补前填写以下清单:

  • 回补业务日期范围:____
  • 触发原因与工单编号:____
  • 涉及上游表与下游表:____
  • 回补任务版本与代码 commit:____
  • 幂等策略:覆盖写 / 删分区写 / 去重写
  • 校验方式:行数对比、指标对比、抽样对比
  • 执行人与审批人:____
  • 回补后是否触发下游重跑:是 / 否

最后要强调:回补是事后修复手段,不是日常数据生产的常规环节。一个健康的风控数据体系,应该通过监控告警、数据质量校验、任务重试机制尽量在前端发现问题,减少回补频率。回补做得越多,说明链路稳定性越差。把回补能力建设好,是为了在真正需要时能够快速、安全、可追溯地恢复数据,而不是为了频繁使用它。