为运维质量、效率和成本保驾护航,携程请了谁来帮忙?
本文根据徐新龙老师在〖2018 Gdevops全球敏捷运维峰会北京站〗现场演讲内容整理而成。
(点击“阅读原文”可获取徐新龙演讲完整PPT)
讲师介绍
徐新龙,携程技术保障中心资深SRE、运维算法工程师,复旦大学信号处理方向硕士研究生毕业。负责携程多个AIOps项目的设计与研发,对人工智能、机器学习、神经网络及数学有浓厚的兴趣,对人工智能技术结合运维场景的实践有深入研究。
大家好,我今天的主题分享主要围绕携程解决应用运维痛点的实践展开。对于保证“运维的质量、效率和成本”这一难题,携程有过非常多的思考,最终是选择了请“AI”这块“他山之石”出手,进行探索和实践。主要内容分为以下四个部分:
应用运维的痛点:列举了我们在做应用运维过程中的一些痛点;
携程AIOps实践之路:为了解决这些痛点,我们在智能化运维方面做的一些实践跟探索;
典型应用场景介绍:就一些实践案例跟大家来分享;
AIOps的一些思索和展望:结合自身的实践,总结下在AIOps方面的一些思考跟展望。
首先从应用的完整生命周期来解释一下,应用运维在整个应用的生命周期中承担了哪些职责:
应用的生命周期
如大家所熟悉的,应用上线要经历过开发、测试、发布、部署,以及后期的运营维护等过程。除应用的开发和测试环节不需要参与外,运维工程师需要参与发布、部署,还有后期的运维监控及分析等重要环节。从更高一点的视角来看,保障网站的可用性和优化数据中心的部署成本,是运维岗位职能和责任中非常重要的两点。
一、应用运维的痛点
下面罗列了一些运维工作中比较有挑战性的共通“痛点”:
第一,应用告警质量不高。刚才聂鑫老师在之前的分享中也介绍了很多关于腾讯告警方面的情况,说明告警问题确实是一个普遍的“痛点”。应用告警的质量不高,准确率、覆盖率、及时性跟不上,会导致一些漏告或者是误告出现。更有甚者,因为应用告警的滞后性,订单都跌零了,但应用告警还没有产生,这就为网站快速恢复故障带来了很大不便。
第二,故障诊断效率低下。应用数量庞大,且应用间调用关系错综复杂,面对应用告警风暴,很难快速定位故障根源,以往排查一个故障,可能数十分钟至小时不等,花费的时间和人力成本很高,不能为及时网站止损。
第三,应用画像的缺失或不完整。应用画像是对功能或行为相似的应用所做的归类,对应用运维的日常工作可以提供非常重要的参考,包括应用的重要性、健康程度、对资源使用的情况(资源画像)等方面。
二、携程AIOps实践之路
基于前面提到的这些“痛点”,接下来就来看看携程AIOps的实践之路。
和运维行业中普遍的经历一样,携程的运维方式主要经历了:
人肉运维的脚本运维时代;
针对特定运维场景的工具化运维时代;
打通端到端应用交付的自动化运维时代;
到现在正在进行中的智能化运维时代。
结合自身的工作经验,刚加入携程的时候正处在脚本跟工具化的运维的时代,整体的自动化程度还不高,一周睡不了几个安稳觉,大半夜经常被电话call起来排查故障。我相信很多一线的运维道友应该身有体会。
后期经过一段时间的野蛮生长,自动化基本覆盖到了运维的绝大部分场景,可以说现在自动化的程度已经非常高。
但随着网站规模和运维数据的积累,我们也发现一些新的问题,像刚才罗列出来的一些,通过传统基于规则的方式很难解决,规则的泛化能力太差,无法满足大数据背景下的运维挑战。针对运维遇到的新的挑战和痛点,借鉴行业中的一些最佳实践经验,开展了携程环境下的智能化运维实践和探索。
行业中对人员的构成上也按照职能的侧重点不同,划分为运维工程师、运维开发工程师和运维AI工程师,大家专业领域不同,分工的侧重也不同:
从我个人的理解看,这种划分大多数情况下只是一种逻辑划分,例如一个人可以身兼多种角色,而这种复合型的人才是目前非常紧缺的。
接着梳理一下携程目前在做的AIOps具体实践场景和方向:
和行业的大多数最佳实践类似,携程的智能化运维主要围绕网站质量、效率和成本等三个方面展开,实践包括异常检测到诊断自愈,以及容量到成本的优化。
从行业整体实践水平来看,目前的AIOps还处于初级阶段,实践的内容主要还是针对单个应用的场景展开。
目前携程的实践场景和方向主要包括:
基于机器学习的通用异常检测平台的建设、基于网络TCP指标统计分析的异常检测(例如TCP指标的RTT、拥塞窗口等指标)、应用和资源画像的构建及完善、精细化Online/Offline混合部署、容量优化,故障根源诊断以及故障自愈方面的研究和探索实践。
下图罗列了比较成熟和典型的实践场景,做了下进一步的场景介绍:
首先是应用监控指标的异常检测,传统基于规则方式的告警泛化能力差,经常会导致告警漏告或者误告,智能告警是通过机器学习的方式替代传统基于固定阈值的告警方式;
当检测到应用指标异常之后,我们通过智能应用诊断系统,诊断系统是基于专家经验和相关性检测等算法实现的故障分析诊断系统,可以快速定位故障根源,从而达到快速止损;
另一实践场景是在线资源和离线作业之间的混合部署,基于对在线应用的资源和离线作业的画像,分时动态地将离线作业调度到在线资源上运行,从而达到提升在线资源利用率的目的,同时也提高了离线作业的执行效率;
最后一个要介绍的是智能弹性扩缩容,通过对线上资源构建容量模型,定期生成容量报告,根据容量报告自动执行扩容和缩容。
三、典型实践场景介绍
背景前面已经介绍过了,数据体量很小的时候,基于规则的告警方式尚可胜任,当数据体量不断增长之后,规则的泛化能力就会变弱。做监控时序的智能异常检测主要是为了提高告警的质量,减少误报和漏告数量、提高告警的及时性、降低阈值管理复杂度。
(1)监控时序指标
首先我们看下常见的监控时序指标,携程是全国最大的在线旅游互联网公司,和大部分互联网公司一样,监控指标根据功能的不同主要分为四大类:
订单指标:也是最核心的监控指标,从监控曲线看有非常强的周期性;
应用指标和业务指标:大部分是开发同事基于框架中间件做的一些业务埋点。这些指标正常情况下都会表现的很平稳,当有突发状况或异常时,指标会剧烈抖动;
基础监控指标:涉及底层各种类型的监控,包括服务器CPU、内存、磁盘IO、网络IO等指标,以及DB、Redis、代理、网络等相关监控指标。
(2)异常检测流程
前面提到了常见的几种监控时序类型,其中最能够及时反映应用健康程度的主要就是应用的监控指标(错误数、请求量以及相应时间等),也是应用运维最关心的指标。
异常检测实践的主要内容也是在围绕业务指标跟应用指标展开的,因为携程的应用数量众多,这部分指标的数量也是非常庞大,非常具有挑战性。前文提到的腾讯聂鑫老师分享的内容中介绍了异常检测的部署架构,那么这里我主要是从数据流向的角度来介绍下时序指标的异常检测:
数据源配置
对于一个通用的异常检测平台而言,待检测的时序数据源可能存在不同的物理介质上,也可能是不同的系统中,为了避免对业务系统的侵入性,异常检测的逻辑一般都是旁路来实现。
首先需要将这些不同系统、不同存储介质中的时序进行采集(数据源可以是DB、Hive、消息、API、以及特定的监控系统等),在异常检测平台中保存一段副本数据,留作构建数据仓库使用。
数据集过滤
但实践中,我们并不会对所有的数据集都配置智能检测算法。原因是因为在很多真实的场景中,有些指标很难用被异常检测的算法检测,主要是因为数据质量不高,有算法经历的道友应该都知道,数据质量的好坏决定了算法效果的上限,如果数据质量很差,再好的算法也可能是无济于事。
所以我们会事先配置了一个数据集过滤模块,过滤掉一些数据质量不高的数据集。
实现的原理主要是基于数据集的一阶和二阶统计量、偏度、峰度、信息熵等指标,将满足一定统计特性的数据集筛选到后续流程处理。
异常检测算法集
针对预筛选环节过滤得到的数据集,我们准备了常见的异常检测算法集,这些算法大都是通用的机器学习算法根据实际情况和需要做了一定的二次定制,更详细的介绍我们会在接下来的内容中展开。
告警状态机
这个模块的功能主要是将时序异常转变为一个有效的告警。从事过监控告警的道友应该有类似的共识,异常数据从统计角度看只是离群较远的分布,能不能当做一个业务告警处理呢?
大部分时候是需要业务同事来给出规则,将一个无语义的时序异常转变成一个业务告警。例如将连续三次或五次的时序异常转变成一个业务告警,连续多少次之后恢复告警,同时告警状态机会维护每个告警的生命周期,避免重复的告警通知等。
告警质量评价
告警质量的评估可以说是最具挑战性的工作了。
一方面,我们检测的指标基本都是无标注的数据集,产生的告警准确与否必须有人来判断;另一方面,因为应用数量众多,每天的告警量也非常的庞大,靠人力逐个去判断几乎是不可能实现的。如果不做告警质量的评价,就无法形成闭环,算法效果也无法得到后续的优化与提升。
我们目前的评价一方面是靠专家经验抽样判断,一方面是邮件将告警推送给监控负责人,通过一定的奖励机制调动用户来反馈告警结果。
(3)异常检测算法介绍
习惯上,按照待检测的数据集有无标签标注可以分为监督式学习、无监督学习以及半监督学习;按照算法模型有无参数将算法分为有参模型和无参模型:
具体算法基本都是大家耳熟能详的,其中大部分算法在实际使用的时候都做过一些二次开发或者参数优化,例如某些场景下我们需要将有的算法改写成递归方式实现,用来适配流方式的处理。
上面只是罗列了部分算法,具体的实现算法要远多于这几种。但就这些异常检测算法的思想进行分类的话,无外乎两大类:
一类是监督式的异常检测,这类算法的数据集因为已经打上了标签的,分成了训练数据集和测试数据集,利用训练数据集和对应的标签训练出模型,然后利用学习到的模型再对测试数据集进行检测;
另外一类算法可以归结为基于分布和统计特性的异常检测,这类型的算法针对的是无标注数据集的检测,一个很简单的道理,我们要判断某个指标正常与否,一定需要和某个基准进行比对,这个基准可以是固定阈值,也可以是动态阈值。基于分布和统计特性的异常检测使用的基本都是动态化的阈值。
(4)基于分布和统计特性的异常检测
在大部分的实践场景中,监控指标都是没有标签标注的,这里我们重点介绍下基于分布和统计特性的异常检测原理。
我们提到的绝大部分监控指标,经过统计分析后都是能够近似满足正态分布或者超高斯分布。利用统计特性做异常检测主要是看分布情况,一个时间轴上的监控序列投影到纵轴上,就可以得到相应的概率密度分布函数,样子如下图所示:
可以看到,水平方向很高的点,对应的概率密度非常小,而大部分监控数据的分布都比较集中。直观的看,连续多次小概率事件发生就可以认为是异常事件,我们借助工业上常用的3Sigma(标准差)准则来作为是否是异常点的检验标准:
对标准的正态分布而言,3Sigma准则可以包括整个样本集99.7%的分布,也就是说有千分之三的样本会被判定为异常。
对于超高斯分布,也就是形状上比标准正态分布更尖的分布,可能用不了3Sigma,2Sigma甚至1Sigma就可以满足检测需求。除了使用标准差外,四分位差也是经常被用作异常检测的动态阈值。
下面是从我们生产系统里截取的一张图,是某个应用的某项监控指标,竖着的虚线标识的时间点代表该指标有监控告警:
可以看到正常情况下这个指标是比较小,按照以往固定阈值的告警方式很难发现这类故障,因为固定阈值动辄就是成百上千的设置阈值,像这种Case,很容易漏掉告警,但是通过分布和统计特性来检测就很容易发现异常。
前面介绍了基于分布和统计特性的异常检测规则,原理上就是基于N Sigma准则方式实现的动态阈值,其中动态阈值是根据预测基线和N倍标准差计算得到的。接下来这个算法主要是跟大家分享下,我们是如何基于时频变换得到预测基线。
时频变换对很多人来讲可能是个比较陌生的概念,用到的技术叫做傅里叶变换。大家可能或多或少都有一点印象,高等数学有一章级数,曾经提到过傅里叶级数。系统讲解傅氏变换的技术是在信号处理这门课程里边介绍的。傅氏变换的物理意义是一个比较烧脑的内容,这里简单介绍下如何应用和实现,具体实现需要对监控序列加窗,然后做离散傅里叶变换。
下面也给出了具体的计算公式,但由于直接计算相当的复杂,实现上都是通过做快速傅里叶变换实现下的,简称FFT:
细节不了解也没啥问题,大家能先有这样一个概念就行。很多编程语言都有现成的函数库,使用的时候调一下,时序的频谱就可以直接计算出来。
通过前面介绍的时频转换技术,将监控时序变换到频率域之后再对频谱做相应的过滤,去除掉频率较高的成分,然后在时间域重构时序,就可以得到一条相对平稳的基线了。这里的前提假设就是我们的监控指标正常情况下都是平稳的,渐变的。从我们系统里边截取了一段基于频域滤波的监控结果:
黄色的曲线是原始的监控指标,绿色的曲线是通过频域滤波之后的基线,可以看到是一条非常平滑和稳定的曲线。从图中可以看到,使用这个技术可以有效的剔除掉异常监控点,确保基线平稳。
基于时频变换的技术,除了前面讲到的可以过滤掉时序中的高频成分生成比较平稳基线时序外,还可以自动发现时序是有包含周期性特征。以这幅图为例为例:
这是从我们系统里边截取的一段真实的监控指标。从肉眼看,确实是存在明显的周期性,现在我们要做的事情是让程序自动的来识别这个指标的周期。
具体的做法是先对这个时序做一个自相关,如图中第2幅所示,然后去掉自相关序列中频率过低和过高的成分,再去掉均值,如图中第3幅所示,这时候结果看上去有点接近正弦波的样子。最后再对上面的结果做一次时频变换就可以得到对应序列的频率谱,如最后一幅图所示。
频率谱左右对称,单位一般为赫兹,频谱上有明显的谱线就说明对应的时间序列存在比较强的周期性,通过一定的数学公式转换,就可以计算出相应的周期大小。
(5)异常检测实践的经验总结
针对前面介绍了关于异常指标检测实践内容,我们简单总结下实践的结果和积累的一些经验,以及识别到的一些问题:
通过智能化告警的实践,应用告警的准确率、召回率相比之前基于规则和固定阈值方式的告警得到了很大的提升。现在携程默认的应用告警方式已经全替换成了智能告警。
然而大部分实践场景中,实现数据都是没有标注的,所以基本都是要结合基于分布和统计特性的异常检测方式。
另外就是并不是所有的时序都是要采用智能化的方式被检测,这里涉及到算力和成本的投入,如果基于规则的方式可以满足某些场景下的告警检测,那么做智能化检测的意义就不是很大,做成这件事主要还是为了解决“痛点”。
还有就是不同时序的特征可能有所不同,而不同的算法适用场景也有所差异,所以针对不同特征的数据集就需要配置不同的检测算法。
至于检测结果的质量评估问题,对于没有标签标注的数据集来说,一直是一个难点,只有这个环节打通,异常检测才算是真正的闭环了。也只有不断地收集和利用反馈结果,这件事才能越来越智能。
我们先来看一个例子,这是一张大量应用告警时的应用大盘截图:
标红的每个方格表示当前有告警的应用。实际应用之间的调用错综复杂,究竟是哪个应用或什么操作导致了此次故障,需要能快速排查出故障原因,这样就可以为网站快速恢复和止损。
作为坚定的唯物主义因果论者,我们借助专家经验,在我们的场景下,把所有可能会影响到某个应用异常的因素罗列出来:
每个子项称为一个因子分析器,其中包括了应用发布、配置变更、调用链异常、代理故障、数据库发布、DNS故障、负载均衡器故障、网络变更等等。
每当发生应用告警的时候,就会自动触发因子分析器分析。引子分析器主要是做运维事件及告警等和应用告警的关联分析,分析结果用百分制打分给出。
主要的算法有两个:一种是基于皮尔逊相关系数计算得到的相关系数;另外一种是基于贝叶斯公式计算得到的后验概率。这两种技术计算的结果,其绝对值都是在0和1之间,相当于对结果做了归因化的处理,然后对这个结果再乘以100就可以直接计算出因子分析器输出的关联分数。
(1)应用的相关性打分、聚合
因子分析器种类特别多,这里我们以应用告警指标和发布事件之间的关联分析为例,说明下相关性打分的原理:
上面黄色的曲线代表了某个告警应用的监控指标,记做序列A;下面的红色的曲线代表了发布事件在时间维度上的量化结果,记做序列B。此时我们就得到了A和B两个时间序列,然后计算下皮尔逊相关系数即可计算得出关联分析结果。
同样的思路我们还可以运用到多个告警应用之间的关联性分析:
图中上线两条曲线分别代表了两个告警应用的监控指标序列,对这两个监控时序直接计算皮尔逊相关系数,即可求得两个告警之间的关联程度。
另外,我们还会通过框架中间记录的埋点数据分析两个应用之间是否存在调用关系,再结合之前计算得到的相关系数,以此来完成将多个应用告警事件进行聚合和收敛。
(2)后验概率打分
利用后验概率打分,需要积累相当长时间的历史运维事件和关联应用告警的数据,记录并收集在运维知识库。这里我们主要对贝叶斯公式的使用做下说明:
使用贝叶斯公式的目的主要是希望从似然概率计算得出后验概率。似然概率是可以通过对知识库的训练和学习得出的某个运维事件发生的时候,各应用告警发生的概率;后验概率刚好是反过来的,是在应用告警的时候,某个运维事件发生的概率大小,而这些运维事件大部分情况下就是对应应用告警的根源。
(3)异常特征知识库匹配
大家都知道,应用报错的异常信息对于故障排查是非常有帮助的。我们如果可以从异常信息中提炼出告警关键字和特征信息,然后利用这些特征信息和以往运维运维数据库训练的结果进行比对,很大程度上也是可以快速匹配出故障根源的。
于是我们对生产环境历史的告警信息进行收集与解析,通过专家标注和训练,记录到运维知识库。每遇到应用告警时,利用告警应用的异常信息进行特征提取和模式匹配,快速定位出故障原因。
下图右侧表格我们列举了不同组织应用告警时匹配到的告警原因标签,对于同一个组织的告警原因基本都匹配到了Redis,则可以判断出此次大规模应用告警基本由于Redis异常引起,为故障排查和定位快速地指明了方向:
上面我们介绍了多种故障关联的方法和实现。实际效果如何呢?下图是从我们生产系统里边截的一张故障时候快速定位根源的快拍:
某天下午突然有很多应用告警同时告警,在我们的故障诊断系统中一键分析就得出了图中的结果,定位的结果非常明显地指向了中间某个应用,而这个应用当时关联到正在做发布。
(4)故障诊断总结
和前面应用告警的智能检测实践一样,我们总结下故障智能诊断的实践成果、经验和识别到的一些问题:
目前大部分故障发生时,我们已经可以快速的定位出故障根源,大大缩短了恢复故障的时间。因子分析器的设计、专家经验知识库的构建、关联打分、调用链挖掘等都是非常关键的技术点。
最后要提到的一点是,诊断质量的结果评估和告警质量的结果评估类似,也是一个技术难点。未来的计划是随着反馈数据的不断积累以及知识库的完善,相信这个问题会逐步得到更好地解决。
(1)混合部署背景
大多数面向用户的在线互联网公司都有类似的场景,业务访问量有明显的波峰和波谷时间。
混合部署背景
白天的访问量高,夜晚的访问量低,对应在线资源的利用率受业务访问量影响也是会出现波峰波谷。相反的,用于跑离线计算和分析的Hadoop、Spark等大数据任务在业务得高峰时间段非常的活跃,相应的离线计算资源利用率在这期间非常的高。
混合部署的目的是在网站业务非高峰时间段将在离线作业调度至在线资源上执行,以此来提高在线资源整体的利用率,同时缓解离线计算任务对离线集群的压力。一方面要保证在线应用的高可用性和低延时,另一方面要尽可能多地提供出更多的在线资源供离线任务使用。
如何做到这点呢?我们主要利用应用画像、在线资源的资源画像以及离线任务的作业画像做一些亲和性的部署,以及对在线应用的保护退出机制。
(2)部署架构
部署架构图可以比较直观地展示混合部署的各个模块:
其中通过离线作业画像筛出一定类型的用户作业,通过应用画像和在线资源的画像筛选出比较空闲的在线资源,然后通过规则引擎和统一调度完成对在线和离线的混合部署。
(3)关键技术及挑战
在整个混合部署中,我们简单总结了涉及到的一些关键技术和挑战:
CPU和IO的隔离是为了避免作业执行期间因为High CPU和网卡流量对在线应用的冲击和影响,隔离的效果决定了相互之间的影响程度;
应用画像、资源画像以及作业画像主要通过聚类算法对感兴趣的特征进行归类,画像的准确性和时效性决定了混合部署的精细化程度;
调度和退出保护机制也是为了更好的保障在线应用的可用性,结合应用响应时长和错误量的智能告警,当在线应用异常时,自动退出专门执行作业的在线实例并转移作业。
(4)资源、应用画像
前面提到我们会将应用及在线资源感兴趣的特征通过聚类算法进行归类,整理成资源和应用画像:
资源属性方面主要是根据基础监控采集到的CPU、内存和IO等方面的指标进行聚类;
业务属性根据应用实际的功能以及在调用链当中所起到的作用划分为四类重要应用;
除了单维度的画像标签外,我们还组合出了一些高级标签,通过对多个单维度做Rank和打分,标识出应用的重要性、健康性、稳定性、活跃性等画像。
(5)混合部署实践效果总结
和前面介绍的实践一样,简单总结下我们在混合部署这块的实践成果、经验以及识别到的一些问题:
资源方面,在业务非高峰时间段,目前可以提供出10%左右的在线资源用来执行离线计算任务;
通过这些在线资源可以分担掉用户45%左右的离线作业数量,这个现象可以用二八原则近似解释,也就是大多数情况下,执行80%的用户离线作业仅使用了20%的计算资源;
通过混合部署,在线资源整体CPU利用前后提升了230%;
同时,因为计算资源和节点数的增加,离线作业的效率也得到了非常明显的提升。
Online/Offline混合部署最直接的经济收益就是减少了离线计算资源的采购成本。除此外,这还是一种降低数据中心部署成本的创新模式。
像离线作业这样极耗CPU和网络IO的应用都可以和在线应用很好地混合部署,这就为其他类型应用的在线混合部署提供了参考和积累了实践经验。
在实践中我们也识别到,如果涉及到跨数据中心的任务调度,因为离线作业需要加载大量数据的原因,网络资源将会是主要瓶颈,这也为我们将来建设新的数据中心提供非常有价值的参考和建设标准。
四、AIOps的一些思考和展望
通过携程在AIOps方面的一些场景实践,我罗列了一些在AIOps方面的一些思考和展望:
AI是“他山之石”:AIOps是一个跨领域结合的技术,AI只是解决运维问题的一种思路和工具,实践的出发点和落脚点还是Ops。另外,较高的自动化程度是AIOps实践的前提。
实践一定要结合自身场景:我们内部一直是主张场景优先的原则,实践AIOps,首先一定要明确自身运维过程中的场景和痛点,不能跟风;警惕拿来主义,AIOps目前没有明确和统一的实践规范,实践前最好要搞清楚机制和原理,必要的时候做一些二次开发。
紧跟行业动态:大型互联网企业有相当的财力和人力做这件事情,而且一般也很乐意分享相关的实践经验。紧随行业的一些最佳实践,结合自身场景分析讨论落地的可行性,可以避免大方向上走弯路。
学术界跟工业界各贡献一半力量:这是清华裴丹教授在各种AIOps会议上分享的时候一直呼吁的,学术界贡献算法,工业界贡献数据和场景,最终实现无人值守的运维愿景。
以上就是本次分享的全部内容,谢谢大家。
近期热文
↓↓↓别忘了点这里可下载PPT~