数据延迟了2小时,老板来问了——任务SLA监控怎么做?
先说结论
任务SLA监控的核心是三件事:① 定义SLA(哪些任务必须在什么时间前完成)→ ② 监控执行(实时追踪任务状态)→ ③ 应急响应(延迟时有标准化的处理流程)。
90%的数据延迟问题可以通过提前监控来预警,而不是等老板发现了再处理。关键在于把监控从「被动发现」变成「主动预警」。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
数据延迟是数据团队最常见的「生产事故」。老板早上8点打开看板,发现昨天的数据还没出来,一个电话打过来——你怎么解释?这道面试题考的不只是技术,更考你有没有一套完整的SLA监控和应急机制。我在每家公司都经历过数据延迟的问题,今天把监控体系和应急流程讲清楚。
什么是数据SLA
SLA(Service Level Agreement)就是「服务承诺」。对数据团队来说,SLA就是:某张报表的数据,必须在每天几点之前产出。
我在某短剧出海公司定的SLA标准是:
| 报表级别 | SLA要求 | 典型报表 | 告警方式 |
|---|---|---|---|
| P0(核心) | 每天8:00前产出 | 日收入报表、广告ROI看板 | 电话+短信+飞书 |
| P1(重要) | 每天10:00前产出 | 用户留存报表、渠道分析 | 飞书群消息+邮件 |
| P2(一般) | 每天12:00前产出 | 内容分析、运营明细 | 飞书群消息 |
| P3(低优) | 当天产出即可 | 临时分析表、测试表 | 不告警 |
注意:SLA不是所有任务都一样的。P0任务和P3任务的要求完全不同,分级管理可以避免告警疲劳。
SLA监控体系怎么搭建
搭建SLA监控分三层:
第一层:任务级监控——每个ETL任务的状态追踪
-- 任务监控表:记录每个任务的执行状态
CREATE TABLE IF NOT EXISTS meta_task_monitor (
task_id STRING COMMENT '任务ID',
task_name STRING COMMENT '任务名称',
dag_name STRING COMMENT '所属DAG',
priority STRING COMMENT '优先级 P0/P1/P2/P3',
sla_deadline STRING COMMENT 'SLA截止时间 如08:00',
ds STRING COMMENT '数据日期',
start_time TIMESTAMP COMMENT '开始执行时间',
end_time TIMESTAMP COMMENT '完成时间',
status STRING COMMENT 'running/success/failed/timeout',
duration_min INT COMMENT '执行耗时(分钟)',
retry_count INT COMMENT '重试次数'
);
第二层:链路级监控——从ODS到ADS的全链路产出时间
单个任务不延迟不代表报表能按时产出。一条链路有5个任务串行依赖,每个任务多跑10分钟,链路就延迟50分钟。所以必须监控整条链路的端到端产出时间。
-- 链路级监控:计算每条关键链路的端到端耗时
SELECT
pipeline_name,
MIN(start_time) AS pipeline_start,
MAX(end_time) AS pipeline_end,
TIMESTAMPDIFF(MINUTE, MIN(start_time), MAX(end_time)) AS total_duration_min,
sla_deadline,
CASE
WHEN MAX(end_time) <= sla_deadline THEN 'ON_TIME'
WHEN MAX(end_time) <= DATE_ADD(sla_deadline, INTERVAL 30 MINUTE) THEN 'WARNING'
ELSE 'BREACH'
END AS sla_status
FROM meta_task_monitor t
JOIN meta_pipeline_config p ON t.dag_name = p.dag_name
WHERE ds = '${bizdate}'
GROUP BY pipeline_name, sla_deadline;
第三层:趋势监控——历史执行时间的趋势分析
有些任务不是突然延迟的,而是每天慢一点、慢一点,直到某天突破SLA阈值。趋势监控可以提前发现这种「温水煮青蛙」的情况。
-- 趋势监控:检查任务执行时间是否在逐渐增长
SELECT
task_name,
ds,
duration_min,
AVG(duration_min) OVER (ORDER BY ds ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS avg_7d,
AVG(duration_min) OVER (ORDER BY ds ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) AS avg_30d,
CASE
WHEN duration_min > 1.5 * AVG(duration_min)
OVER (ORDER BY ds ROWS BETWEEN 29 PRECEDING AND CURRENT ROW)
THEN 'ANOMALY'
ELSE 'NORMAL'
END AS trend_status
FROM meta_task_monitor
WHERE task_name = 'dws_revenue_daily'
ORDER BY ds DESC
LIMIT 30;
-- 如果最近7天均值 > 30天均值的1.3倍,说明在恶化
数据延迟的常见原因和应对
| 延迟原因 | 占比 | 表现 | 解决方案 |
|---|---|---|---|
| 上游数据源延迟 | 30% | ODS层数据没到 | 联系上游/设置弹性等待 |
| 资源争抢 | 25% | 任务排队等资源 | 资源隔离/优先级队列 |
| 数据倾斜 | 20% | 某个Task卡住 | 加盐打散/AQE/调参数 |
| 代码变更引入问题 | 15% | 新上线后变慢 | 上线前Review/灰度发布 |
| 基础设施故障 | 10% | 集群/网络异常 | 多集群容灾/自动切换 |
应急响应SOP
数据延迟发生后的标准处理流程:
Step 1(0-5分钟):确认范围。哪些任务延迟了?影响哪些报表?是P0还是P3?
Step 2(5-15分钟):快速定位。看任务日志——是失败了还是卡住了?是数据源没到还是计算慢了?
Step 3(15-30分钟):临时处理。如果是数据源没到,先用昨天的数据临时补上,保证报表有数据。如果是计算慢,先加资源让P0任务优先跑。
Step 4(30分钟+):根因修复。数据源的问题联系上游;计算慢的问题优化SQL或调参数。
Step 5(事后):复盘+预防。写复盘文档,更新监控规则,防止同类问题再次发生。
# 延迟告警脚本示例
def check_sla_breach():
now = datetime.now()
tasks = get_pending_tasks() # 获取还在跑的任务
for task in tasks:
deadline = parse_time(task.sla_deadline)
remaining = (deadline - now).total_seconds() / 60
if remaining < 0:
# 已经超时
send_alert(task, level='CRITICAL',
msg=f'{task.name} 已超过SLA {abs(remaining):.0f}分钟')
elif remaining < 30:
# 即将超时
send_alert(task, level='WARNING',
msg=f'{task.name} 距SLA还有{remaining:.0f}分钟,当前状态: {task.status}')
# 每5分钟执行一次
schedule.every(5).minutes.do(check_sla_breach)
面试高频追问
追问一:所有任务都需要SLA监控吗?
不是。只有P0和P1任务需要严格的SLA监控和告警。P2任务做趋势监控就行,P3任务不监控。我们在出海硬件公司有500+个ETL任务,但配了SLA的只有40个(核心报表链路上的任务)。监控太多会导致告警疲劳,大家就不看告警了。
追问二:数据延迟了但老板急着要数据怎么办?
两个临时方案:一是用T-2(前天)的数据临时展示,在报表上标注「数据延迟中,当前展示为前天数据」;二是如果只差一两个任务没跑完,手动触发只跑P0链路的最小依赖,其他非关键任务暂停让资源。我在出海硬件公司遇到过集群故障导致全面延迟的情况,就是用第二种方案保住了P0报表。
追问三:怎么防止数据延迟频繁发生?
三个方面:一是资源预留——给P0任务预留专属资源队列,不和其他任务争抢。二是趋势监控——发现任务执行时间在逐渐增长时提前优化,不要等到超时才处理。三是定期优化——每个季度Review一次核心链路的执行效率,数据量增长了但SQL没优化的要及时处理。
实战踩坑
我在某短剧出海公司遇到过一次严重的数据延迟。某天早上8点,P0的收入报表没出来,老板直接打电话过来。排查后发现原因是:前一天运营跑了一个临时的大查询(全量扫描了一张10亿行的表),把集群资源吃满了,导致P0的ETL任务排队等了2个小时。
这个事故让我意识到:没有资源隔离的集群是不安全的。临时查询和生产ETL混在同一个队列里,一个大查询就能拖垮所有生产任务。
-- 资源隔离方案:Hive/Spark资源队列配置
-- 生产ETL队列(高优先级,预留50%资源)
SET mapreduce.job.queuename = production;
-- 或者Spark
SET spark.yarn.queue = production;
-- 临时查询队列(低优先级,弹性资源)
SET mapreduce.job.queuename = adhoc;
-- YARN资源队列配置示例
-- production: capacity=50%, max-capacity=80%, priority=HIGH
-- adhoc: capacity=30%, max-capacity=50%, priority=LOW
-- default: capacity=20%, max-capacity=30%, priority=NORMAL
-- 这样即使adhoc队列被打满,production队列仍有50%资源保障
解决方案:配置了YARN资源队列后,P0任务有了专属资源保障。同时在临时查询平台上加了资源限制——单个查询最多使用10%的集群资源,超过的需要走审批。改完之后再也没因为临时查询导致生产延迟。
总结
任务SLA监控的核心是:分级定义SLA(P0-P3)+ 三层监控(任务级、链路级、趋势级)+ 标准化应急响应。面试时重点讲「资源隔离」和「主动预警」两个关键点。记住:好的SLA监控不是在延迟发生后告警,而是在延迟发生前预警。
下一篇聊一个很多数据团队都有的问题:数据仓库里一半的表没人用——数据资产盘点和治理怎么做?
你们的核心报表SLA是几点?有没有被老板追过数据延迟的经历?评论区聊聊~
关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长