nigh 2019-01-21
携程的应用数量众多、架构复杂,规模效应和时间维度上的积累会导致运维数据(日志、监控数据、应用信息等)体量异常庞大,传统基于经验规则的方式已经不能很好地胜任某些特定的运维场景。特别是在大数据时代背景下,这种挑战尤为严峻。
本文将分享携程在 AIOps 方面的一些探索和典型的实践场景,希望通过分享,让大家对 AIOps 以及目前行业发展水平有个宏观的认识,也给对 AIOps 感兴趣的小伙伴一些借鉴和启发。
运维数据的体量随着运维规模的快速增长呈现出爆发式地增长。除了对持续交付、持续集成、资源调度、监控能力等提出很高的要求外,面对海量的运维数据,其查找和获取成本也变得非常高。
另外,运维数据的价值和数据成本之间如何平衡、如何取舍,以及如何挖掘有价值的信息,也给运维提出了一定的挑战。
结合自身实践以及通过对行业整体水平的分析,介绍下对 AIOps 的理解、定位和现状,以及发展 AIOps 面临的一些挑战。
AIOps 现状及实践内容
从行业分享的最佳实践内容看,AIOps 主要围绕质量、效率和成本这三个方面展开,实践包括异常检测到诊断自愈,以及容量到成本的优化。
从行业整体实践水平来看,目前的 AIOps 还处于初级阶段,实践的内容主要还是针对单个应用的场景展开。
发展 AIOps 的挑战
因为是跨领域结合的技术,所以发展的难度也主要是两个领域的知识都需要有比较深刻的理解和认识。数据质量和算法积累是一方面挑战,复合型人才的稀缺是另一方面。
单场景实践方面罗列了几个相对成熟的解决方案。
从 AIOps 整体架构设计和规划方面,主要分为四个逻辑层实现。自顶向下分别包括:运维 KPI 层、运维场景解决方案层、平台自动化层、以及底层基础架构和数据监控层。
底层服务为上次的实现提供能力和平台支撑,未来重点主要会放在平台能力的建设和优化、以及更多智能化运维场景的挖掘方面。
具体的实践运维场景以监控时序的异常检测和应用的智能诊断为例展开介绍:
监控时序的异常检测
数据体量很小的时候,基于规则的告警方式尚可胜任,当数据体量不断增长之后,规则的泛化能力就会变弱。做监控时序的智能异常检测主要是为了提高告警的质量,减少误报和漏告数量、提高告警的及时性、降低阈值管理的复杂度。
监控时序指标
首先总结下常见的监控时序指标,携程是国内最大的在线旅游互联网公司,和大部分互联网公司一样,监控指标根据功能的不同主要分为以下几类:
订单指标,也是最核心的监控指标,从监控曲线看有非常强的周期性;
应用指标和业务指标,大部分是开发基于框架中间件做的一些业务埋点。这些指标正常情况下都会表现的很平稳,当有突发状况或异常时,指标会剧烈抖动;
基础监控指标,涉及底层各种类型的监控,包括服务器 CPU、内存、磁盘 IO、网络 IO 等指标,以及 DB、Redis、代理、网络等相关监控指标。
异常检测流程
前面提到了常见几种监控时序类型,其中最能够及时反映应用健康程度的就是应用的监控指标(错误数、请求量以及相应时间等),也是应用运维最关心的指标。
异常检测实践的主要内容也是在围绕业务指标跟应用指标展开的,因为携程的应用数量众多,这部分指标的数量也是非常庞大,非常具有挑战性。这里我们主要介绍从数据流向的角度来介绍下时序指标的异常检测。
异常检测算法介绍
习惯上,按照待检测的数据集有无标签标注可以分为监督式学习、无监督学习以及半监督学习;按照算法模型有无参数将算法分为有参模型和无参模型。
具体算法基本都是大家耳熟能详的,其中大部分算法在实际使用的时候都做过一些二次开发和参数优化,例如某些场景下我们需要将有的算法改写成递归方式实现,用来适配流方式的处理。
上面只是罗列了部分算法,具体的实现算法要远多于这几种。但就这些异常检测算法的思想进行分类的话,无外乎两大类:
一类是监督式的异常检测,这类算法的数据集因为已经打上了标签的,分成了训练数据集和测试数据集,利用训练数据集和对应的标签训练出模型,然后利用学习到的模型再对测试数据集进行检测;
另外一类算法可以归结为基于分布和统计特性的异常检测,这类型的算法针对的是无标注数据集的检测,一个很简单的道理,我们要判断某个指标正常与否,一定需要和某个基准进行比对,这个基准可以是固定阈值,也可以是动态阈值。基于分布和统计特性的异常检测使用的基本都是动态化的阈值。
在大部分的实践场景中,监控指标都是没有标签标注的,这里我们重点介绍下基于分布和统计特性的异常检测原理。
我们提到的绝大部分监控指标,经过统计分析后都是能够近似满足正态分布或者超高斯分布。利用统计特性做异常检测主要是看分布情况,时间轴上的监控序列投影到纵轴上,就可以得到相应的概率密度分布函数。从成图直观的看,连续多次小概率事件发生就可以认为是异常事件。
我们借助工业上常用的 3Sigma(标准差)准则作为是否是异常点的检验标准,对标准的正态分布而言,3Sigma 准则可以包括整个样本集 99.7% 的分布,也就是说有千分之三的样本会被判定为异常。
对于超高斯分布,也就是形状上比标准正态分布更尖的分布,可能不用 3Sigma,2Sigma 甚至 1Sigma 就可以满足检测需求。除了使用标准差外,四分位差也是经常被用作异常检测的动态阈值。
下面是从我们生产系统里截取的一张图,是某个应用的某项监控指标,竖着的虚线标识的时间点代表该指标有监控告警。可以看到正常情况下这个指标是比较小,按照以往固定阈值的告警方式很难发现这类故障,因为固定阈值动辄就是成百上千的设置阈值,像这种 Case,很容易漏掉告警,但是通过分布和统计特性来检测就很容易发现异常。
前面介绍了基于分布和统计特性的异常检测规则,原理上就是基于 N Sigma 准则方式实现的动态阈值,其中动态阈值是根据预测基线和 N 倍标准差计算得到的。接下来这个算法主要是跟大家分享下,我们是如何基于时频变换得到预测基线。
时频变换对很多人来讲可能是个比较陌生的概念,用到的技术叫做傅里叶变换。大家可能或多或少都有一点印象,高等数学有一章级数,曾经提到过傅里叶级数。系统讲解傅氏变换的技术是在信号处理这门课程里边介绍的。
理解傅氏变换的物理意义是很有挑战性,这里简单介绍下如何应用和实现,具体实现需要对监控序列加窗,然后做离散傅里叶变换。下面也给出了具体的计算公式,但由于直接计算相当的复杂,实现上都是通过做快速傅里叶变换实现下的,简称 FFT。很多编程语言都有现成的函数库实现。
通过前面介绍的时频转换技术,将监控时序变换到频率域之后再对频谱做相应的过滤,去除掉频率较高的成分,然后在时间域重构时序,就可以得到一条相对平稳的基线了。
这里的前提假设就是我们的监控指标正常情况下都是平稳的,渐变的。从我们生产系统里边截取了一段基于频域滤波的监控结果,黄色的曲线是原始的监控指标,绿色的曲线是通过频域滤波之后的基线,可以看到是一条非常平滑和稳定的曲线。从图中可以看到,使用这个技术可以有效的剔除掉异常监控点,确保基线平稳。
基于时频变换的技术,除了前面讲到的可以过滤掉时序中的高频成分生成比较平稳基线时序外,还可以自动发现时序是有包含周期性特征。
以这幅图为例为例,这是从生产系统里边截取的一段真实的监控指标。直观的看,确实是存在明显的周期性,现在我们要做的事情是让程序自动的来识别这个指标的周期。
首先对这个时序做一个自相关,如图中第 2 幅所示,然后去掉自相关序列中频率过低和过高的成分,再去掉均值,如图中第 3 幅所示,这时候结果看上去有点接近正弦波的形状。最后再对上面的结果做一次时频变换就可以得到对应序列的频率谱,如最后一幅图所示。
频率谱左右对称,单位一般取赫兹,频谱上有明显的谱线就说明对应的时间序列存在比较强的周期性,通过一定的数学公式转换,就可以计算出相应的周期大小。
异常检测实践的经验总结
针对前面介绍的关于异常指标检测实践内容,我们简单总结下实践的成果和积累的一些经验,以及识别到的一些问题。
通过智能化告警的实践,应用告警的准确率、召回率相比之前基于规则和固定阈值方式的告警得到了很大的提升。
现在携程默认的应用告警方式已经全替换成了智能告警。大部分实践场景中,这些时序数据都是没有标注的,都是需要结合基于分布和统计特性的异常检测方式。
另外并不是所有的时序都是要采用智能化的方式被检测,这里涉及到算力和成本的投入,如果基于规则的方式可以满足某些场景下的告警检测,那么做智能化检测的意义就不是很大,做成这件事主要还是为了解决“痛点”。
另外就是不同时序的特征可能有所不同,而不同的算法适用场景也有所差异,所以针对不同特征的数据集就需要配置不同的检测算法。
再提一下检测结果的质量评估问题,对于没有标签标注的数据集来说,一直是一个难点和挑战,只有这个环节打通,异常检测才算是真正的闭环了。也只有不断地收集和利用反馈结果,这件事才能越来越智能。
应用告警的智能诊断
我们先来看一个例子,下面是一张大量应用告警时的应用大盘截图,标红的每个方格表示当前有告警的应用。实际应用之间的调用错综复杂,究竟是哪个应用或什么操作导致了此次故障,需要能快速排查出故障原因,这样就可以为网站快速恢复和止损。
作为坚定的唯物主义因果论者,我们相信万事皆有因果。借助专家经验,我们把所有可能会影响到某个应用异常的因素罗列出来,每个子项称为一个因子分析器,其中包括了应用发布、配置变更、调用链异常、代理故障、数据库发布、DNS 故障、负载均衡器故障、网络变更等等。
每当发生应用告警的时候,就会自动触发因子分析器分析。引子分析器主要是做运维事件及告警等和应用告警的关联分析,分析结果用百分制打分给出。
主要的算法有两个:一种是基于皮尔逊相关系数计算得到的相关系数;另外一种是基于贝叶斯公式计算得到的后验概率。这两种技术计算的结果,其绝对值都是在 0 和 1 之间,相当于对结果做了归因化的处理,然后对这个结果再乘以 100 就可以直接计算出因子分析器输出的关联分数。
应用的相关性打分、聚合
因子分析器种类特别多,这里我们以应用告警指标和发布事件之间的关联分析为例,说明下相关性打分的原理。
上面黄色的曲线代表了某个告警应用的监控指标,记做序列 A;下面的红色的曲线代表了发布事件在时间维度上的量化结果,记做序列 B。此时我们就得到了 A 和 B 两个时间序列,然后计算下皮尔逊相关系数即可计算得出关联分析结果。
同样的思路我们还可以运用到多个告警应用之间的关联性分析。图中上线两条曲线分别代表了两个告警应用的监控指标序列,对这两个监控时序直接计算皮尔逊相关系数,即可求得两个告警之间的关联程度。
另外,我们还会通过框架中间记录的埋点数据分析两个应用之间是否存在调用关系,再结合之前计算得到的相关系数,以此来完成将多个应用告警事件进行聚合和收敛。
后验概率打分
利用后验概率打分,需要积累相当长时间的历史运维事件和关联应用告警的数据,记录并收集在运维知识库。这里我们主要对贝叶斯公式的使用做下说明,使用贝叶斯公式的目的主要是希望从似然概率计算得出后验概率。
似然概率是可以通过对知识库的训练和学习得出的某个运维事件发生的时候,各应用告警发生的概率;后验概率刚好是反过来的,是在应用告警的时候,某个运维事件发生的概率大小,而这些运维事件大部分情况下就是对应应用告警的根源。
上面我们介绍了多种故障关联的方法和实现。实际效果如何呢?这幅图是从我们生产系统里边截的一张故障时候快速定位根源的快拍。
某天某时突然有很多应用告警同时告警,在我们故障诊断系统中一键分析就得出了图中的结果,定位的结果非常明显地指向了中间某个应用,而这个应用当时关联到正在做发布。
故障诊断总结
和前面应用告警的智能检测实践一样,我们总结下故障智能诊断的实践成果、经验和识别到的一些问题。
目前大部分故障发生时,我们已经可以快速的定位出故障根源,大大缩短了恢复故障的时间。因子分析器的设计、专家经验知识库的构建、关联打分、调用链挖掘等都是非常关键的技术点。
要提到的一点是,诊断质量的结果评估和告警质量的结果评估类似,也是一个技术难点。未来的计划是随着反馈数据的不断积累以及知识库的完善,相信这个问题会逐步得到更好地解决。
通过携程在 AIOps 方面的实践和探索,最后简单总结下我们在 AIOps 方面的一些思考和展望。
AI 是“他山之石”:AIOps 是一个跨领域结合的技术,AI 只是解决运维问题的一种思路和工具,实践的出发点和落脚点还是 Ops。另外,较高的自动化程度是 AIOps 实践的前提。
实践一定要结合自身场景:我们一直是主张场景优先的原则,实践 AIOps,首先一定要明确自身运维过程中的场景和痛点,不能跟风;警惕拿来主义,AIOps 目前没有明确和统一的实践规范,实践前最好要搞清楚机制和原理,必要的时候做一些二次开发。
紧跟行业动态:大型互联网企业有相当的财力和人力做这件事情,而且一般也很乐意分享相关的实践经验。紧随行业的一些最佳实践,结合自身场景分析讨论落地的可行性,可以避免大方向上走弯路。
学术界跟工业界各贡献一半力量:这是清华裴丹教授在各种 AIOps 会议上分享的时候一直呼吁的,学术界贡献算法,工业界贡献数据和场景,最终实现 AIOps 的美好愿景。
AIOps 总体来说是一个比较新和初期的技术,预测 5 到 10 年后,运维必将是另外一番景象。相信通过构建敏锐的“眼”、智慧的“脑”以及自动化的“手”,“无人值守的运维”的美好愿景终将能实现。
作者简介
徐新龙,携程技术保障中心资深 SRE,复旦大学信号处理方向硕士研究生。负责携程多个 AIOps 项目的设计与研发,对人工智能、机器学习、神经网络及数学有浓厚的兴趣,对人工智能技术结合运维场景的实践有深入研究。