订阅更新

业务说「数据不准」,你怎么排查?——数据质量问题排查SOP

数据治理手册 第 4 题 约 9 分钟读完

本文目录
  1. 先说结论
  2. Step 1:确认问题——先别急着查代码
  3. Step 2:定位层级——沿血缘从下往上追
  4. Step 3:常见根因分类
  5. Step 4:修复与复盘
  6. 排查效率提升:从2小时到15分钟
  7. 面试高频追问
  8. 实战踩坑
  9. 总结

先说结论

排查「数据不准」有一套标准的SOP,分四步:① 确认问题(和业务对齐口径)→ ② 定位层级(沿血缘从ADS往上追)→ ③ 找到根因(数据源/ETL逻辑/参数配置)→ ④ 修复+复盘。

80%的「数据不准」问题,其实不是数据真的错了,而是口径不一致。「), t(」所以排查的第一步不是看代码,而是先问清楚:「你说的'不准「是什么意思?跟哪个数据对不上?」

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

「数据不准」是数据开发最怕听到的四个字。业务找你说「这个数据不对」,你心里一紧——到底是真的不对,还是业务理解有偏差?这道面试题考的不是你会不会修Bug,而是你有没有一套系统化的排查流程。我来分享一下我在实际工作中总结出来的排查SOP。

Step 1:确认问题——先别急着查代码

我在某短剧出海公司遇到过一个典型案例。运营说「昨天的新增用户数不对,少了很多」。我第一反应就是去查ETL,但后来发现:运营看的是广告平台(Facebook Ads)上报的新增数,我们的数仓统计的是App内注册的新增数。一个是「广告点击→安装」,一个是「安装→注册」。两个口径本来就不一样,根本不是数据质量问题。

所以排查的第一步,永远是确认以下信息:

# 排查问题前的5个必问问题
# 1. 你看的是哪个报表/看板?(确认数据源)
# 2. 你觉得正确的数据应该是多少?(确认期望值)
# 3. 你是跟什么对比发现不对的?(确认对比基准)
# 4. 这个问题是今天才出现的还是一直都有?(确认时间范围)
# 5. 有没有截图?(确认具体数值)
 
# 经验:问完这5个问题,50%的case当场就解决了
# 因为很多时候是口径不一致或者业务看错了看板

Step 2:定位层级——沿血缘从下往上追

如果确认了确实是数据有问题(不是口径问题),接下来就要定位问题出在数仓的哪一层。思路很简单:从最下游的ADS层开始,沿着血缘一层层往上追。

-- 定位层级的核心思路:逐层核对数据
 
-- Step 2.1: 先看ADS层的数据
SELECT * FROM ads_daily_report WHERE ds = '2024-01-15' AND metric_name = 'new_users';
-- 结果:new_users = 5000(业务说应该是8000左右)
 
-- Step 2.2: 往上看DWS层
SELECT ds, COUNT(DISTINCT user_id) AS new_users
FROM dws_user_daily
WHERE ds = '2024-01-15' AND is_new = 1;
-- 结果:new_users = 5000(和ADS一致,说明ADS层的聚合逻辑没问题)
 
-- Step 2.3: 再往上看DWD层
SELECT ds, COUNT(DISTINCT user_id) AS new_users
FROM dwd_user_register
WHERE ds = '2024-01-15';
-- 结果:new_users = 5000(DWD也一样,说明问题不在ETL聚合)
 
-- Step 2.4: 看ODS层的原始数据
SELECT ds, COUNT(*) FROM ods_register_log WHERE ds = '2024-01-15';
-- 结果:只有5200条(正常应该是8000+),问题在数据源!

通过这个逐层排查,我发现问题出在ODS层——数据源的Kafka消费出了延迟,有一部分数据没有在当天被消费完。这种「从下往上追」的方法,通常2-3步就能定位到问题层级。

Step 3:常见根因分类

问题分类典型表现常见原因解决方案
数据源问题ODS层数据量异常Kafka延迟/埋点丢失/API超时联系上游修复+数据回补
ETL逻辑错误某一层数据突然变化JOIN条件错误/过滤条件遗漏修复逻辑+重跑下游
口径不一致数据「不准」但技术无错业务/产品/数据三方口径不同统一口径文档
参数配置错误数据整体偏移时区/分区/阈值配置错误修正配置+重跑
环境问题某天数据为空或异常任务失败/资源不足/依赖超时重跑任务

我的经验是:50%是口径问题,20%是数据源问题,15%是ETL逻辑错误,10%是参数配置,5%是环境问题。口径问题最多,但最容易解决——只要和业务把口径文档对齐就行。

Step 4:修复与复盘

找到根因后,修复的流程是:

① 修复数据:如果是数据源丢失,联系上游做数据回补。如果是ETL逻辑错误,修复逻辑后重跑。重跑一定要用INSERT OVERWRITE确保幂等。

② 验证修复:修复后跑一遍数据质量校验(对比修复前后的数据),确认问题已解决。

③ 复盘沉淀:写一个简单的复盘文档:什么时候发现的、影响范围、根因、修复措施、后续预防措施。

-- 修复后的验证SQL:对比修复前后的数据
SELECT
  '修复前' AS version, ds, COUNT(DISTINCT user_id) AS new_users
FROM dwd_user_register_backup  -- 修复前的备份表
WHERE ds = '2024-01-15'
GROUP BY ds
UNION ALL
SELECT
  '修复后' AS version, ds, COUNT(DISTINCT user_id) AS new_users
FROM dwd_user_register
WHERE ds = '2024-01-15'
GROUP BY ds;
-- 对比两个version的数据,确认修复正确

排查效率提升:从2小时到15分钟

刚开始排查数据问题的时候,我平均要花2个小时。后来总结出上面这套SOP之后,效率大幅提升。关键的几个工具和方法:

1. 血缘系统:直接看到影响链路,不用手动翻代码找上下游关系。

2. 数据质量看板:每天自动校验核心表的数据量、NULL率、值域分布。很多问题在业务反馈之前就已经发现了。

3. 口径文档:所有核心指标的计算口径、数据源、负责人都记录在案。业务来问「不准」的时候,先查口径文档。

-- 口径文档的核心字段示例
-- 指标管理表 metric_definition
-- | metric_id | metric_name | definition | formula | data_source |
-- | owner | update_time | status |
 
-- 例如:
-- metric_id: m_001
-- metric_name: 日新增用户数
-- definition: 当天首次在App内完成注册的去重用户数
-- formula: COUNT(DISTINCT user_id) WHERE is_first_register = 1
-- data_source: dwd_user_register
-- owner: Wood
-- status: 已审核

面试高频追问

追问一:排查过程中如果涉及多个团队,你怎么协调?

我的做法是:先自己定位到问题的大方向(数据源还是ETL),然后拉一个临时群,把相关的人(客户端/后端/数据/业务)都拉进来。在群里说清楚三件事:现象是什么、初步定位是什么、需要谁配合查什么。不要一个个私聊,效率太低。紧急问题拉群解决,15分钟对不齐就直接拉会。

追问二:怎么预防「数据不准」的问题?而不是每次出了问题再排查?

三个层面:第一,数据质量自动化监控(上一篇讲过的四性校验);第二,ETL代码Review机制(每个SQL上线前必须有人Review);第三,口径管理制度化(新指标必须先定义口径再开发)。我在出海硬件公司把这三件事做到位后,数据质量工单从每月15+降到了5-6个。

追问三:如果业务坚持说数据不对,但你查完发现数据是对的,怎么处理?

这种情况其实很常见。我会准备一份详细的数据验证报告——从ODS到ADS每一层的数据截图、核心SQL、关键数字——发给业务方看。同时找到他们的对比基准(比如第三方平台的数据),解释清楚两边口径的差异在哪里。关键是态度要好,不要让业务觉得你在推卸责任。

实战踩坑

我在某短剧出海公司排查过一个非常诡异的问题。运营说「某个国家的收入突然降了50%」。我查完整个链路发现数据没问题,ODS到ADS每一层都对得上。最后花了一下午才发现:问题出在时区。

我们的出海业务涉及多个时区。ETL里统一用UTC时间处理,但运营看的报表用的是当地时间。有一个国家(巴西)的时区从UTC-3切换成了夏令时UTC-2,导致UTC的「当天」少了一个小时的数据。报表上看就是收入少了。

-- 跨时区数据处理的正确做法
-- 1. ODS层:保留原始UTC时间
-- 2. DWD层:同时保留UTC和当地时间
SELECT
  event_id,
  event_time_utc,
  -- 转换为当地时间(考虑夏令时)
  FROM_UTC_TIMESTAMP(event_time_utc, user_timezone) AS event_time_local,
  -- 当地日期分区(报表用这个)
  DATE(FROM_UTC_TIMESTAMP(event_time_utc, user_timezone)) AS local_date
FROM ods_event_log;
-- 核心原则:存储用UTC,展示用当地时间
-- 报表的ds分区应该基于local_date而不是UTC date

解决方案:我们把报表的时间分区从UTC date改成了local_date,并且维护了一张时区映射表(包含夏令时信息)。改完之后这类问题再也没出现过。这个经验在面试中讲出海业务的数据挑战时特别好用。

总结

排查「数据不准」的SOP四步法:确认问题→定位层级→找根因→修复复盘。面试时记住一句话:80%的「数据不准」其实是口径问题。所以排查的第一步不是查代码,而是和业务对齐口径。能讲出这个洞察,面试官会觉得你有实际经验。

下一篇聊一个让数据团队和业务团队经常扯皮的话题:同一个指标,两个部门算出来不一样——指标口径一致性怎么管?

你遇到过最难排查的「数据不准」问题是什么?评论区分享一下~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器