2. 故障排查方法论:MTTR 模型、日志分层策略、告警分级机制
做实时特征平台这几年,我最大的感触是:故障一定会来,区别只在于你多久能发现、多久能恢复。今天咱们就聊聊故障排查的底层逻辑——MTTR 模型、日志怎么分层、告警怎么分级。这些东西看着是方法论,其实都是血泪换来的。
2.1 MTTR 模型:把故障时间拆开看
MTTR 全称 Mean Time To Repair,平均修复时间。但说实话,我更愿意把它拆成四个阶段:
| 阶段 | 英文 | 说明 | 我见过的典型耗时 |
|---|---|---|---|
| 发现 | MTTD | 从故障发生到有人感知 | 30秒~5分钟 |
| 定位 | MTTI | 从感知到找到根因 | 5分钟~2小时 |
| 修复 | MTTR | 从定位到恢复服务 | 1分钟~30分钟 |
| 复盘 | MTTA | 从恢复到完成复盘 | 1小时~1天 |
你看,真正花时间的往往是定位阶段。我记得有一次线上特征延迟,团队花了 3 个小时才找到原因——原来是 Kafka 的一个 broker 磁盘满了。如果日志和告警设计得好,这个时间完全可以压缩到 10 分钟以内。
核心思路:不要试图优化所有阶段,先盯着 MTTI(定位时间)打。定位快了,整体 MTTR 自然就降下来了。
2.2 日志分层策略:别让日志变成噪音
很多人喜欢打日志,恨不得每行代码都打一条。结果呢?故障来了,日志文件几十个 G,根本看不下去。我个人的习惯是按层级管理日志,就像整理衣柜一样——常穿的挂外面,不常用的收起来。
2.2.1 分层模型
我把实时特征平台的日志分成四层:
- L1 - 业务日志:记录特征计算的核心链路。比如「用户 12345 请求特征 A,耗时 12ms,结果返回成功」。这是排查业务问题的一手资料。
- L2 - 系统日志:记录组件状态。比如 Kafka 消费延迟、Flink checkpoint 失败、Redis 连接池耗尽。这些是排查基础设施问题的关键。
- L3 - 调试日志:记录详细参数和中间结果。平时不开,只有定位疑难杂症时才打开。比如某个特征值为什么算出来是 null。
- L4 - 审计日志:记录操作行为。谁在什么时间改了配置、发布了版本、重启了服务。用于事后追责和合规。
我的建议:L1 和 L2 必须实时采集、实时索引。L3 可以写到本地文件,按需拉取。L4 走单独的存储,不要和业务日志混在一起。
2.2.2 日志格式规范
我曾经踩过一个坑:日志格式不统一,排查时 grep 出来的结果乱七八糟。后来我们定了统一格式:
[时间] [级别] [模块] [请求ID] [关键字段] 消息内容
示例:
[2025-03-15 14:23:11.456] [ERROR] [feature-calc] [req-abc123] [user_id=10086] 特征A计算超时,耗时2500ms
为什么要加请求ID?你想想看,实时特征平台每秒处理几万次请求,没有请求ID,你根本没法把一次请求的日志串起来。
2.3 告警分级机制:别让告警变成狼来了
告警太多,团队会麻木。告警太少,故障漏了。怎么平衡?我的做法是按影响面分级。
2.3.1 四级告警体系
| 级别 | 名称 | 响应要求 | 举例 |
|---|---|---|---|
| P0 | 紧急 | 立即响应,5分钟内介入 | 特征服务全部不可用、数据延迟超过10分钟 |
| P1 | 严重 | 15分钟内响应 | 部分特征不可用、延迟超过3分钟 |
| P2 | 警告 | 1小时内响应 | 单节点故障、CPU超过90%持续5分钟 |
| P3 | 通知 | 下一个工作日处理 | 磁盘使用率超过70%、日志报错率上升 |
注意:P0 告警必须走电话或短信,不能只发群消息。我见过不止一次,P0 告警发到群里没人看,等发现时已经过去半小时了。
2.3.2 告警去重与抑制
实时特征平台经常出现「告警风暴」——一个底层故障引发几十个上层告警。怎么处理?
- 依赖关系抑制:如果 Redis 挂了,所有依赖 Redis 的特征计算告警自动降级为通知,不重复报警。
- 时间窗口聚合:同一类告警在 5 分钟内只发一次,合并展示发生次数。
- 静默期:人工确认后,同类告警静默 30 分钟,避免干扰修复过程。
2.4 知识体系总览
下面这张图把 MTTR 模型、日志分层和告警分级串在了一起。你可以把它当作故障排查的「作战地图」。
2.5 实战建议:从理论到落地
说了这么多,怎么落地?我分享几个实操经验:
- 先定告警,再写代码:每次上线新特征,先把告警规则写好。别等出问题了再补,那时候手忙脚乱。
- 日志必须带上下文:单条日志要有足够的信息独立判断。我曾经见过一条日志只写了「error」,连哪个模块、哪个请求都不知道,这种日志等于没有。
- 定期演练:每季度做一次故障演练,模拟 P0 场景。你会发现很多平时想不到的问题——比如告警没发出来、值班电话打不通、操作手册过时了。
- 复盘要写改进项:每次故障复盘,必须输出至少一个可执行的改进项。不要只写「加强监控」这种空话,要写「给 Redis 连接池添加告警,阈值设为 80%」这种具体动作。
一个小技巧:我习惯在代码里埋一个「健康检查」接口,返回当前服务的所有关键指标。故障时先调这个接口,能快速判断是哪个环节出了问题。比翻日志快多了。
嗯,以上就是故障排查方法论的三个核心。MTTR 模型帮你拆解时间,日志分层让你快速定位,告警分级确保你不会漏掉真正的故障。这三样东西配合好了,实时特征平台的稳定性就有了基本保障。