ETL 任务失败排查
场景描述
凌晨 3 点 ETL 任务失败,早上发现数仓 DWD 层数据为空,下游所有报表受影响。
排查流程
常见失败原因及处理
| 错误类型 | 典型日志 | 处理方法 |
|---|---|---|
| OOM | Container killed by YARN for exceeding memory | 增大内存或优化 SQL |
| 数据源变更 | Table or column not found | 上游改了表结构,适配 |
| 分区不存在 | Partition (dt=2024-01-15) not found | 上游任务未完成,等待重跑 |
| 数据质量 | Quality check failed: null_rate > 10% | 检查源数据,决定是否降级 |
| 超时 | Task timed out after 3600 seconds | 优化 SQL 或调大超时时间 |
| 锁冲突 | Deadlock found when trying to get lock | 错峰执行或优化事务 |
应急处理 SOP
1. 止血:确保下游可用
# 方案一:降级到 T-2 数据(旧数据总比没数据好)
# 方案二:跳过质量检查强制产出(标记数据质量降级)
# 方案三:手动用临时 SQL 快速产出核心表
2. 修复:处理根因
-- 如果是 OOM,优化 SQL
-- 改前:全表 JOIN
SELECT a.*, b.* FROM huge_table a JOIN another_huge_table b ON a.id = b.id;
-- 改后:先过滤再 JOIN
SELECT a.*, b.*
FROM (SELECT * FROM huge_table WHERE dt = '2024-01-15') a
JOIN (SELECT * FROM another_huge_table WHERE dt = '2024-01-15') b
ON a.id = b.id;
3. 补数:回填缺失数据
# Airflow 回填命令
airflow dags backfill --start-date 2024-01-15 --end-date 2024-01-15 dag_dwd_order
4. 复盘:防止复发
| 维度 | 复盘内容 |
|---|---|
| 根因 | 为什么失败? |
| 影响 | 哪些报表受影响?影响了多少用户? |
| 时效 | 从失败到恢复用了多长时间? |
| 改进 | 如何避免下次再发生? |
常见面试问题
Q1: 如何预防 ETL 任务失败?
答案:
- 依赖管理:用 Airflow Sensor 检查上游就绪再执行
- 超时和重试:设置合理超时,自动重试 2-3 次
- 资源隔离:核心任务独立队列,不被其他任务影响
- 告警:任务失败立即告警(短信 + 企微),不要等到早上才发现
- 数据质量检查:在关键节点加 dbt test
Q2: Airflow 任务卡住不动怎么排查?
答案:
- 查 Worker 状态:Worker 是否健康、是否有空闲 Slot
- 查 Pool:是否达到 Pool 并发上限
- 查依赖:上游 Sensor 是否一直在等待
- 查 Scheduler:Scheduler 进程是否正常
- 查日志:Worker 日志中是否有死锁或连接池耗尽