阿里集团针对故障处理提出了“1/5/10”的勇攀因分目标-- 1 分钟发现、5 分钟定位、监控10 分钟恢复,高峰这对我们的勇攀因分定位能力提出了更高的要求。 业界已经有好多在做根因分析的了,但是大都准确率不高,大部分还在 40% 到 70% 之间,从侧面说明根因分析确实是一个难啃的骨头。 1、SOA 服务入口; 2、Http 服务入口; 3、MQ 消费消息入口; 4、定时 job 入口; 具体是哪些远程操作属性受到影响了? 是客户端到服务器端的网络受到影响了? 是服务器端出了问题吗? 在明确了我们要解决的问题以及要求的故障结论之后,我们要采取什么样的方案来解决呢?下面首先会介绍一个基本功能「指标下钻分析」。 1、针对入口服务的响应时间和成功率判断是否异常,若无异常则无根因可分析; 2、针对入口服务的 5 种操作进行指标下钻分析,得出异常波动的操作类型有哪些; 3、然后到对应操作类型的指标中再次进行指标下钻分析,得出该操作下: a.哪些入口受到该操作的波动影响了? b.哪些操作属性异常波动了? c.假如该操作是远程操作,还要继续深入服务器端进行分析: 假如你有远程操作数据的 3 要素的话,那么是可以分析出: 客户端建立连接、发送请求和接收响应耗时问题; 网络耗时问题; 服务器端耗时问题。 假如服务器端耗时正常的话,那就相对划分为客户端发送请求或接收响应耗时是根因; 假如服务器端耗时异常抖动的话,那么就需要到服务器端进行深入分析; 比如 DB 操作来说,可以继续深入到 DAL 层面分析。 某个 table 的所有操作耗时抖动? 某条 SQL 操作耗时抖动? 某台具体 DB 实例抖动? SQL 的停留时间 or 执行时间抖动? 比如客户端的 RPC 操作来说,可以继续递归到远程 appId 的根因分析流程: 阿里本地生活的根因分析能力,1 个月内从产生根因分析的想法到实现方案上线到生产(不包括指标下钻分析的实现,这个是之前就已经实现好的了),1 个月内在生产上实验和优化并推广开来,总共 2 个月内实现了从 0 到 1 并取得了如下成绩: 1、50 个详细记载的案例中准确定位 48 次,准确率 96%; 2、最高一天执行定位 500 多次; 3、平均定位耗时 1 秒; 我认为主要是以下 3 个方面: 我认为主要是以下 2 方面的原因: 案例一 依赖的 AppId3 的 SOA 服务抖动。 依赖的 AppId5 的本地处理和 Redis 操作耗时抖动。 依赖的 AppId6 的本地处理和 Redis 操作耗时抖动。 依赖的 AppId4 的本地处理和 Redis 操作耗时抖动。背景
根因分析建模
要解决什么样的问题
举个例子:现有一个应用,拥有一堆容器资源,对外提供了诸多 SOA 服务或者 Http 服务,同时它也依赖了其他应用提供的服务,以及 DB 资源、Redis 资源、MQ 资源等等,那我们如何才能够全面的掌控这个应用的健康状况呢?我们需要掌控:1、掌控这个应用的所有入口服务的「耗时」和「状态」2、掌控每个入口服务之后每种操作的「耗时」和「状态」一个应用都有哪些入口? 故障的结论
有了上述数据的全面掌控,当一个故障来临的时候,我们可以给出什么样的结论?1、哪些入口受到影响了?2、受影响的入口的本地操作受到影响了?3、受影响的入口的哪些远程操作受到影响了? 根因分析实现
指标下钻分析
一个指标,有多个 tag,当该指标总体波动时,指标下钻分析能够帮你分析出是哪些 tag 组合导致的波动。比如客户端的 DB 操作抖动了,利用指标下钻分析就可以分析出:1、哪个机房抖动了?2、哪个 dal group 抖动了?3、哪张表抖动了?4、哪种操作抖动了?5、哪个 sql 抖动了?再比如远程 RPC 操作抖动了,利用指标下钻分析就可以分析出:1、哪个机房抖动了?2、哪个远程 appId 抖动了?3、哪个远程 method 抖动了?其实这个就是去年 AIOPS 竞赛的题目,详细见:http://iops.ai/competition_detail/?competition_id=8&flag=1通常的方案:1、对每个时序曲线都要进行数据预测,拿到预测值;2、针对每个方案根据实际值和预测值的差异算出一个方案分数;3、遍历所有可能性方案,挑选出分数最高的方案(通过蒙特卡洛树搜索进行剪枝优化)。我们的方案:1、确定整体的波动范围;2、确定计算范围= 该波动范围 + 前面一段正常范围,在计算范围内算出每根时间线的波动值(比如波动的方差,实际肯定不会这么简单,有很多的优化点);3、对所有时间曲线进行一些过滤(比如和整体抖动方法相反,整体都向上抖动,它向下抖动);4、对过滤后的时间曲线按照波动值进行 KMeans 聚类;5、从排名靠前的分类中挑选出方案,为每个方案计算方案分数(这个方案个数就非常之少了);6、得出分数最高的方案。针对去年的决赛题目,我们的这个方案的跑分达到了 0.95 以上,应该就在前三名了。 根因分析流程
有了指标下钻分析功能之后,我们来看如何进行根因分析:落地情况
准确率为什么这么高?
1、数据的完整度
假如是基于采样链路去分析,必然会存在因为漏采导致误判的问题。我们分析的数据是全量链路数据转化成的指标数据,不存在采样的问题,同时在分析时可以直接基于指标进行快速分析,临时查采样的方式分析速度也是跟不上的。 2、建模的准确性
你的建模方案能回答出每个 SOA 服务抖动的根因分别是什么吗?绝大部分的建模方案可能都给不出严谨的数据证明,以 DB 是根因为例,他们的建模可能是 SOA 服务是一个指标,DB 操作耗时是一个指标,2 者之间是没有任何关联的,没有数据关联你就给不出严谨的证明,即没法证明 DB 的这点抖动跟那个 SOA 服务之间到底有没有关联,然后就只能处于瞎推测的状态,这里就必然存在误判的情况。而我们上述的建模是建立了相关的关联,我们会统计每个入口后的每种操作的耗时,是可以给到严谨的数据证明。 3、异常判定的自适应性
比如 1 次 SOA 服务整体耗时 1s,远程调用 RPC1 耗时 200ms,远程调用 RPC2 耗时 500ms,到底是哪个 RPC 调用耗时抖动呢?耗时最长的吗?超过一定阈值的 RPC 吗?假如你有阈值、同环比的限制,那么准确率一定不高的。我们的指标下钻分析在解决此类问题的时候,是通过当前情况下的波动贡献度的方式来计算,即使你耗时比较高,但是和之前正常情况波动不大,那么就不是波动的根因。 速度为什么这么快?
业内领先的时序数据库 LinDB
根因分析需要对诸多指标的全量维度数据进行 group by 查询,因此背后就需要依靠一个强大的分布式时序数据库来提供实时的数据查询能力。LinDB 时序数据库是我们阿里本地生活监控系统 E-Monitor 上一阶段的自研产物,在查询方面:强悍的数据压缩:时序数据原始数据量和实际存储量之比达到 58:1,相同 PageCache 的内存可以比别的系统容纳更多的数据;高效的索引设计:索引的预过滤,改造版的 RoaringBitmap 之间的 and or 操作来进行高效的索引过滤;单机内充分并行化的查询机制:利用 akka 框架对整个查询流程异步化。整体查询效率是 InfluxDB 的几倍到几百倍,详细见文章--分布式时序数据库 - LinDB :https://zhuanlan.zhihu.com/p/35998778 指标下钻分析算法的高效
我们不需要每个时间线都进行预测;实际要计算的方案个数非常之少;方案算分上可以适应于任何加减乘除之类的指标计算上,比如根因定位中的平均响应时间 = 总时间 / 总次数SOA1 的平均响应时间 t1 和 SOA2 的平均响应时间 t2,SOA1 和 SOA2 的总体平均响应时间并不是 t1 和 t2 的算术平均而是加权平均,如果是加权平均,那么久需要多存储一些额外的信息,并且需要进行额外的加权计算。 实际案例
直接点击根因分析,就可以分析到如下结果:
AppId1 的 SOA 服务在某个机房下抖动了:1、依赖的 AppId2 的 SOA 服务抖动。
AppId4 的 1 个 SOA 方法抖动:1、该方法的本地处理抖动(实际是获取 Redis 连接对象 Jedis 的耗时抖动);2、该方法依赖的 Redis 操作抖动;3、该方法抛出 Redis 连接异常;
案例二
故障现场如下,某个应用的 SOA 服务抖动上升。点击根因分析,就可以帮你分析到如下结果:
AppId1 的 SOA 服务在某个机房下抖动了:1、依赖的 AppId2 的 SOA 服务抖动,依赖的 DB 服务抖动。2、依赖的 AppId3 的 SOA 服务抖动,依赖的 AppId2 的 SOA 服务抖动,依赖的 DB 服务抖动。点击 AppId2,可以看下详细情况,如下所示:
从表格中就可以看到,根因是 DB 的一台实例抖动导致这个 dal group 所有操作抖动。
作者信息:
李刚,网名乒乓狂魔,饿了么监控组研发专家,饿了么内部时序数据库 LinDB 的项目负责人,饿了么根因分析项目负责人,目前致力于监控的智能分析领域以及下一代全景监控的体系化构建。林滨(予谱),饿了么监控组前端工程师,现负责一站式监控系统 EMonitor 的前端开发,旨在将繁杂的数据以高可视化输出。