背景介绍
AntMonitor:蚂蚁集团研发的一款面向云原生时代的全功能智能运维产品,包含业务监控、应用监控、基础设施监控、云原生可观测、一站式多维分析等功能。其中,智能化的单指标异常检测是该产品最基础、最重要的组成部分。
针对时序异常检测,目前蚂蚁集团内部基本都在按照以下几个思路进行研发:
- 通过时序预测的方法,典型算法为 ARIMA、LSTM 等,将历史数据训练的模型预测当前时刻的幅值,通过与真实值的差异来判断此刻的异常程度。在多次尝试此类模型后发现,其不但算法复杂度较高,还存有隐藏风险,此类模型训练遵循的是全局最优化策略,因此在预测当前值时无法保证当前值是单点最优(运气不好的情况下,当前点预测值误差较大)。一种解决的思路是结合其他算法进行集成学习,将误差概率尽可能的降低;
- 采用深度学习的方法,通过大量采集正负样本,采用一维 CNN、甚至二维 CNN (将时序数据视为图像)的方法训练模型。在尝试该类方法后发现,虽然其能够解决一些无法用规则描述的异常场景,但要搭建一个合适的针对时序数据的网络模型难度较大,此外在当前异常标准没有完全统一的情况下,模型移植性存在着很大的问题,当不同的 SRE 对业务容忍阈值不一致时,意味着要针对性地重新训练模型,这个工作量是十分巨大的;
- 通过集成学习的方法,有项目组是将多个弱分类赋予权重后投票来解决异常识别问题,当前的效果是在部分场景中可以达到很高的准招率。但与传统 Ensemble Learning 不同的是,其各个弱分类器的权重调整并不是一个自优化过程,而是需要通过人工调整获得,这在检测指标数量不大的时候可以采用,但是针对 AntMonitor 动辄几十万个目标指标的场景就无解了;
- 通过统计规则与机器学习相结合的方法,需要尽可能地将异常场景进行分类剥离(或者对数据进行分类,即算法路由),再针对各个场景进行求解。其中机器学习或深度学习可以用于描述一些难于公式化的场景,如描述波形相似。此类方法还可以将模型内部的各个参数进行透传,可以兼顾计算效率和模型移植性;
上述几种思路无所谓优劣,不同的方法都有其优势及不足,都有其契合及尴尬的场景,合适的方法才是最好的方法。针对 AntMonitor 实际面对的运维场景,统计规则和机器学习相结合的方法被选为最终解决方案。本文将分享研发 AntMonitor 智能检测算法时的一些想法和思路,欢迎各位交流学习。
异常分类
在做智能异常检测的过程中,其中最棘手的问题是获得一个明确的异常判断标准。比较遗憾的是,针对不同的业务、不同的指标甚至不同的使用方都会有不同的判断标准。因此,本文从另一个角度出发,先挖掘认可度高的基础异常波形,再以点到面逐步地解决异常判断问题。以耗时值上升异常检测为例,下图给出了 AntMonitor 常见异常波形 A-D(各种异常波形都可认为是以下几种波形的变种或组合),根据各自不同的特性将其归纳为3种不同的类型,分别为冲高异常、趋势抬升异常和频率变化异常。其中 A、B 归为冲击异常,从图中可以看到其都有一个显著的幅值突变;C 归为缓变抬升异常,相较与冲击异常,其幅值抬升过程相对较为平缓;D 归为频率变化异常,主要特征为波动频率出现巨大的变化。下面分别对不同类型异常进行求解。
图1 常见异常波形
算法整体架构
图2 为整体算法架构,其主要由 preFilter、coreUp 和 adapter 三部分组成。preFilter 为前置过滤器,能够在较少数据输入的情况下过滤绝大部分正常信号,极大地降低资源消耗,这是算法能够大规模覆盖的基础;coreUp 为核心检测层,通过算法路由将不同类型数据映射到对应到合适的算法参数或模块,主要对冲击、趋势和频率三种异常类型进行检测;adapter 为适配层,其主要作用是能够允许不同对象创建适合自身的异常检测模型,其中可通过透出的算法进行人工配置,也可以通过样本打标来自动训练最优模型参数。下一章节主要对 coreUp 层几个核心模块的具体实现做详细介绍。
图2 算法整体构架
核心模块介绍
冲击异常模块
冲击异常在波形上表现为某时刻突然出现的一个尖峰,往往是局部的幅值极大值。然而直接从幅值触发判断当前点是否异常,往往会出现漏报。如图3所示,由于原始波形存在着趋势项,冲击波形虽然是局部及极大值但往往不是全局视野内的最大值,因此会有被过滤的可能。观察冲击异常波形,发现其往往都是瞬时“变化”最大的时刻,其显著特征是当前值远大于前一时刻的值或持续大于前值。因此,本节从寻找瞬时波动幅值突变点的角度出发,开发基于一阶差分的异常检测算法。
当间距相等时,用下一个值减去上一个值定义为“一阶差分”。如图3所示,当带有趋势项的时间序列经过一次差分后可以有效地去除趋势项,同时冲击异常点也从局部极大值转变为了全局最大值。针对长度为的时间序列,其对应差分序列可以表示为, 其中。若当天时间序列与历史事件序列分别用和表示,分别计算各自差分序列得到和, 同时获得当前时刻差值。若在集合和同时被判定为异常,则意味着当前时刻存在着冲击异常可能。考虑到存在着连续上升的情况,在实际应用中对差分计算稍作修改使其更为精确,例如当满足时,令。
图3 时序趋势的影响
常用的异常检测方法可参考异常检测算法综述类论文。此处采用 Tukey 箱型图作为异常检测算法。选择箱线图算法的原因主要有三点:1)计算简单; 2)可适用于非正态分布数据; 3)可调整判断阈值。
Tukey 箱型图
此处对 Tukey 箱线图分析做一下简单介绍。众所周知,基于正态分布的 3σ 法则或 Z 分数方法的异常检测是以假定数据服从正态分布为前提的,但实际数据往往并不严格服从正态分布。应用这种方法于非正态分布数据中判断异常值,其有效性是有限的。Tukey 箱型图是一种用于反映原始数据分布的特征常用方法,也可用于异常点识别。在识别异常点时其主要依靠实际数据,因此有其自身的优越性。箱线图的绘制方法是:
- 先找出一组数据的最大值、最小值、中位数和两个四分位数;
- 然后,连接两个四分位数画出箱子;
- 再将最大值和最小值与箱子相连接,中位数在箱子中间;
箱线图为我们提供了识别异常值的一个标准:异常值被定义为小于 Q1-1.5IQR 或大于 Q+1.5IQR 的值。虽然这种标准有点任意性,但它来源于经验判断,经验表明它在处理需要特别注意的数据方面表现不错。
图4 箱线图示意图
冲击检测流程
冲击异常检测的简要流程如下:
- 当日序列和历史序列,获得差分序列和,已经当前差分值;
- 采用Turkey箱线图获得集合的上限,判断是否超限,若否返回“正常”,若是进入下一步;
- 判断异常时刻是否超过预设异常持续时长,若否返回“正常”,若是进入下一步;
- 在中截取以当前时刻为中心且长度为的子集合,采用 Turkey 箱线图获得其上限,判断是否超限,若否返回“正常”,若是进入下一步;
- 判断在当日前序时间序列中是否也存在冲高异常点,若不存在返回“异常”结果;若存在进入下一步;
- 判断是否大于,若是返回“异常”结果,若否则返回“正常”结果;
图5 冲击检测流程
存在的问题
采用上述方法存在两个问题,第一个如下左图所示,若出现大幅度下跌回升(相当于下跌检测中的冲高回落)的情况,当前点的差分值必然会超限告警,这种误报当前通过类似“冲高回落”的方法进行过滤,本文不再具体介绍;第二种,在整体波动幅度较大的情况下,出现这种小幅缓变抬升的小凸起,采用冲击异常检测是无能为力的。针对这种异常类型,本文通过趋势异常模块来进行解决。
图6 存在的漏报场景
趋势异常模块
当波形缓慢上升时,由于差值大小是基本稳态的,上述冲击异常模块是无法有效识别的。因此,必须要有方法支持此类缓慢变化异常识别。在尝试各种算法模型后,本文最终选择 AugmentedDickey–FullerTest 和 Mann-Kendall Test 相结合的方式来求解此类问题。
ADF Test
Mann-Kendall 非参数秩次检验原理如下,对长度为的时间序列, 统计假设:未经调整修正的数据系列是一个由个元素组成的独立的具有相同分布的随机变量。备择假设是双边检测:对所有的,当时和时和的分布不相同。计算时,对每一个,与其后的进行比较,记录出现的次数。定义 Mann-Kendall 统计量 :
其中, 为符号函数。当小于、等于或者大于零时,分别为-1、0或者1;对于假设统计,当时,的分布为正态分布,的均值为,方差为。当时,即可应用近似正态分布进行检验分析。
标准整体统计变量可以用下式计算:
这样,在双边的趋势检验中,在给定的置信水平上,如果则原假设是不可接受的。为正值表示增加趋势,负值表示减少趋势。的绝对值在大于等于1.28、1.64、2.32时表示分别通过了信度为90%、95%、99%的显著性检验。
Mann-Kendall 非参数秩次检验在数据趋势检测中极为有用,其特点表现为:
- 无需对数据系列进行特定的分布检验,对于极端值也可参与趋势检验;
- 允许系列有缺失值;
- 主要分析相对数量级而不是数字本身,这使得微量值或低于检测范围的值也可以参与分析;
- 在时间序列分析中,无需指定是否是线性趋势;
趋势检测流程
趋势检测并不是直接检测当日数据是否存在上涨趋势,理论上若历史数据与当天数据同步上涨,那么该波形趋势不应该识别为异常。换句话说,需要去除当日数据相对于历史的趋势。此处采用相对差值的方式来实现该目的。假设当日数据为 = ,某天历史数据为 = ,那么两者之间的差值序列可以表示为,在此基础上再进行趋势分析。
详细流程如下:
- 计算当日数据与某历史数据的相对差值序列;
- 采用 Mann-Kendall 检验判断是否存在上涨趋势,若无上涨趋势返回“正常”结果,反之进入下一步;
- 计算趋势上涨的起始点,采用最小二乘法拟合上涨段波形,获得上涨绝对幅值, 计算当日数据中点对应的基础值,计算实际上涨比率;
- 判断是否大于设定涨幅比率阈值,若不大于设定阈值则返回“正常”结果,反之则进入下一步;
- 采用T检验判断前序数据是否存在类似的上涨波形,若存在则返回“正常”结果,若不存在则返回“异常”结果;
图7 单次趋势检测流程
实际应用中流程会稍复杂一点,并且做了部分假设:1)若当天相对于昨日不存在上涨趋势,即可认为不存在缓变上涨异常;2)若当天相对于昨日存在上涨趋势,那么需考察当天相对与剩余历史是否也存在上涨趋势,此处设定若有大于天不存在相对趋势,即认为不存在缓变趋势。考虑到算法需要获得准确的告警时间点,并用来计算精确的涨幅比率,此处对按不同长度先后进行趋势判断。大致的判断流程如图13所示,此处不再展开。
图8 趋势上涨异常检测整体流程
频率异常模块
频率异常在实际场景中并不多见,但是作为一类异常类型,此处也对其进行了覆盖。针对频率异常数据类型,本文采用分位数聚合特征来进行求解,主要步骤如下:
DoulbeRollingAggregate
分位数定义:对一个有着连续分布函数的样本集,分位数是将一个概率分布切分为有着相同概率的连续区间的切分点。用数学公式表达的话:,则称为随机变量的分位数。
分位数聚合特征计算流程如下:
- 长度为的时间序列,分别扩展得到的时间序列和,具体为:;
- 对时间序列进行滑窗截取操作,窗口长度为,获得长度为的子序列集合,其中;同样的,获得时间序列对应的子序列;
- 计算集合中各个子序列的个分位数,用表示子序列的分位数;同样的,计算集合中各个子序列的对应的分位数,用表示;
- 通过和获得当前时刻的分位数聚合特征,具体公式如下:
分位数聚合特征计算示意图如下所示:
图9 分位数聚合特征计算示意图
实际检测效果
在频率异常检测的应用中,需要对数据类型进行区分。针对稀疏类型数据直接进行“分位数聚合”算法计算,而对于存在趋势项的非稀疏数据,必须先对其进行一阶差分操作后才可以使用当前算法。图10给出了两者不同类型的频率异常检测模型,分别给出了“分位数聚合”特征曲线,从图中可以看到可以准确地识别此类异常波形。在实际使用中还需要根据具体场景添加一些规则限制,此处不再具体展开。
图10 不同类型异常数据检测效果
相似性检测模块
相似性误报在时序异常检测中占有不小的比例。如下图时序在检测时刻出现异常冲高时,若不考虑历史同期波形,往往会出现相似性误报现象。实际在波形进行相似性检测时,往往需要考虑时序长短不一致和波形偏移的问题。一般来讲,时序长短不一致和波形偏移主要表现为:
- 如下图所示,当日波形$$T_0$$与历史波形的冲高部分出现一段前后偏移;
- 为提高实时检测的时效性,一般参考将历史参考波形相对于当前检测时刻延后几分钟;
图11 相似性误报
由于时序长短不一致和波形偏移的情况,皮尔逊相关系数、余弦相似度、欧式距离等相似性评价指标就不再适用。动态时间规整(DTW)是一种常用的模板匹配算法,其可以有效的解决对比长度不一致的时间序列相似性问题,图12给出了DTW算与传统欧式距离评价的差异,此处不再展开描述。但实际应用中,DTW 算法更多的是一种搜索匹配算法,即其返回结果是目标库中的最优匹配对象,而在时间序列实时监测过程中,需要的是能给出一个可量化的相似度参考值做为判断依据,因此 DTW 也不能直接使用。本文给出了一种基于动态时间规整(DTW)及T检验的时序波形相似性评估方法,不但能够有效评估长度不同、发生偏移序列的相似度,还可以返回可量化的相似性度量值,能够应用于时间序列实时异常检测。
图12 DTW 算法与欧式距离对比
相似性检测流程
- 截取当日数据,记时间序列为 = , 表示当前时刻的实时数据;
- 截取历史同时刻对比数据,记为 = , 为了刻画数据偏移特性,历史对比数据比当天数据往后多取个数据点;
- 为消除时序常数项对距离度量的影响,对时序做“拉平”预处理,即将各个时间序列减去其自身中位数,获得新的序列分别记为和;
- 定义时序到时序的距离定义为,分别计算当日与各个历史的距离,获得距离集合,此处 和 的长度分别为和;
- 分别计算内两两时序的距离,获得距离集合,为与上一步骤保持一致,此处中波形取数据前个点,取个点;
- 采用STest算法判断集合和中的距离均值和是否存在显著性差异,设原假设:,备择假设:,检验水准;
- 计算获得pValue,若pValue>,不拒绝原假设,表明当日波形与历史波形相似; 反之,当日波形与历史波形不相似;
实际检测效果
下图给出了“相似性检测模块”的实际检测效果,图13中的4例告警都为未配置“相似性检测”模块前的上升告警样例,采用上述算法回跑后都可以有效地识别为相似性误报。从实际使用情况来看,该模块评估为误报的案例基本都是相似的,反之存在着一定的偏差,但对于一个后置过滤模块来讲是完全可接受的。总体来讲,对较为规整的波形判断效果不错,当历史数据本身趋势不相关、波形太过杂乱,上述算法效果一般。
图13 相似性检测效果
算法过滤场景
通过上述整体算法判断后,下图中的潜在异常场景,如单点冲高、冲高前序相似、冲高历史相似、抬升历史相似等都可以被有效过滤。在实际应用中,此类过滤项都配置有相应的开关,由业务人员来确认是否开启。
图14 典型过滤场景
总结与展望
本文算法总体思路是对单指标波形异常检测问题进行拆解,将其归纳为冲高异常、趋势上涨异常和频率变化异常三个模式。在此基础上,辅以一些过滤模块来减少特定误报的产生,如利用基于 DTW 的算法来求解诸如"波形相似性"的误报场景。此外,本文中的异常判断标准相对统一,都以箱线图分析为标准,各个超参数都可以进行透传,后期针对不同的应用场景不同的阈值都可以快速调整。当前根据以上思路设计的模型主要应用在 JVM&System 指标监测上,约 5w 条 key 总体异常告警量小于5条/分钟。
基本上,上述算法可以覆盖绝大部分的场景,但往往会有各种意想不到的误报漏报情况出现,后期的一部分工作要重点解决此类问题;另一方面,针对一些偏明确的场景,在后期可以用机器学习或者深度学习模型来进行代替,如“波形相似性”问题,在积累足够样本量后可尝试通过深度学习模型进行覆盖。同时,也可以尝试集成算法,以往从事机器学习的项目经验表明,往往集成后会有意想不到的精度提升。
作者简介
徐剑,花名辂远,蚂蚁集团高级开发工程师,工学博士,长期从事智能运维、机器学习和信号处理等领域的研究及开发工作,当前为 AntMonitor 算法开发人员。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。