自动异常检测旨在发现复杂业务指标(请求量、收入等)的异常波动,是智能监控系统中的重要环节。百度的业务种类繁多,各业务的监控需求迥异,参数配置成本繁重,给异常检测带来了巨大的挑战。本文整理了运小博在 2017CNUTCon 全球运维技术大会上分享的《百度大规模时序指标自动异常检测实战》和在 CCF TF“人工智能时代的互联网运维”主题研讨会中分享的《百度智能运维实践之异常检测》的内容。主要介绍百度运维部 IOP 团队开发的自动异常检测系统及其核心技术能力,并重点讨论了大规模时序异常检测参数配置成本高的问题。演讲展示了三种常用异常检测算法及其适用场景,并基于此讨论了算法的自主选择策略,以及每种算法的参数自动配置方法。
异常检测需要监控的业务繁多,覆盖了搜索、广告、地图、糯米等百度大部分的产品业务。及时发现这些业务请求数、拒绝数、响应时间、流水和订单等数据的异常波动,是业务稳定性的重要保证。这些数据不但数量众多,而且不同业务的曲线也有截然不同的特征。从上图的三幅曲线图可以看出:
第一幅曲线图中有蓝、绿两根曲线,分别代表当前时刻数据和上周同一时刻的数据。蓝色曲线几乎完全覆盖了绿色曲线,说明数据有规整的周期特性。
第二幅曲线图中,紫色曲线是当前时刻数据,蓝色曲线是上一周的数据。可以看出:数据有一定的周期性,但又不如第一幅图那么规整。
第三幅曲线图中的数据大致平稳,在某些时段出现了异常上涨。
所以,我们的异常检测系统面临两个挑战:一是数据规模大—总共有百万量级的指标;二是曲线的特征差异明显,监控难度大。
通用场景的异常检测算法
对曲线特征进行梳理后,我们发现大多数曲线都可以分数到下面三个场景中:
场景一:数据无规律波动,但正常基本在一个较小的波动范围内,典型的场景就是拒绝数监控,通常我们会按照拒绝数的常态波动范围设定一个或多个恒定阈值,超过阈值即报警。
场景二:数据的长期波动幅度较大,但正常情况下短期的波动幅度较小,体现在图像上是一根比较光滑的曲线,不应该有突然性的上涨或者下跌。典型的场景包括糯米的订单、流水。这类场景监控的主要思想就是环比附近的数据,检查是否存在突然的大幅上涨或下跌。
场景三:数据有规律地周期性波动,比如广告收入或搜索流量等。检测这类数据的方法是与历史数据作同比,从而发现异常。
恒定阈值类算法
场景一的问题可以使用恒定阈值解决,超过设定阈值就报警。比如拒绝数监控,我们可以设定在一个单位时间内超过 100 个拒绝就报警。但是,实际使用中会出现单点毛刺的问题,也就是一个单点超过阈值的报警。当数据来回抖动时,就会产生大量无效报警。常见方法就是通过 filter 来解决,比如设置为连续 5 个时刻都超过阈值才报警,但这种方法太过僵硬,中间只要有一个点回到阈值范围内就不报。
我们采用的是更加柔性的累积法:一段时间窗口内数据的均值超过阈值触发才报警。这样不但能够滤除毛刺,还考虑了原始数据的累计效应。
突升突降类算法
场景二要解决的是突升突降的问题,我们求取数据最近两个窗口的均值变化比例(见上图公式),将原始数据转换到了变化比例空间(r 空间),如右下的小图所示。在 r 空间上设置阈值就可以检测出数据的突升或突降。
同比类算法
场景三中的数据有显著的周期性,我们计算历史上相同时间窗口内数据的均值和标准差,然后计算当前点的 z-score 值,即当前点的值减去均值之后再除以标准差。逐点计算 z 值可以把原始数据转换到另外一个空间(z 空间),在 z 空间设置阈值就可以发现这类异常了。比如左下的小图里蓝色曲线是当前的数据,红色和绿色的曲线是历史同时刻数据。如果要检测图中红色圆圈的部分是否异常,我们以历史数据(红色方块内的数据)为基准计算均值和标准差。右下的小图展示了蓝色曲线在 z 空间的形态,如果取值位于红色阈值线的下方,即可报警。
算法选择决策树 &参数自动配置算法
不同曲线需要选取不同的算法,大量曲线的算法选择成本很高。例如,右上的小图是某产品在不同省份的流量数据,我们看到流量大的省份(如北京、广东)的曲线周期性很明显,更适合同比算法,流量小的省份比如西藏的曲线基本区域平稳,更适合配置恒定阈值。
另外,算法在不同时段的参数不同,工作日和休假日的参数、白天和晚上的参数都不同,参数配置成本非常高。
除此之外,曲线特征会随着业务系统的架构调整发生相应的变化,算法和参数需要定期维护。例如右下的小图是某个子系统的流量数据,箭头时刻这个子系统下线了,此事算法和参数都需要做出相应调整。
因此,我们希望帮助用户自动选择算法和配置参数。接下来我们将分别介绍算法选择决策树和参数自动配置算法。
算法选择决策树
曲线配置算法本质上在建立数据特点与算法本身的映射。周期性数据选择配置同比算法,非周期数据会通过波动范围来界定。当数据的全局波动(长期波动)远大于局部波动(短时波动)的时候,我们倾向于选择突升突降;当全局波动近似等于局部波动的时候,恒定阈值算法就会更合适。
接下来需要解决的问题就是:如何判断数据是否有周期性?如何界定数据的全局与局部波动范围?
我们提出了一种基于差分的数据周期特征判断方法。先将临近的两天数据做差分,如果是周期数据,差分后就可以消除掉原有数据的全局波动,然后结合方差的阈值判断就可以确定数据是否有周期性。实验发现,不同天的数据有一定的上下浮动,因此差分之前可以先对数据做归一化。
前面的方法能够分离出周期性数据,接下来要度量数据的全局波动和局部波动的相对大小。数据方差可以直接表达全局波动范围。对数据施加小尺度的小波变换可以得到局部波动,局部波动的方差反应了局部波动的大小。
结合周期性数据的判断方法和数据的全局、局部波动的表示,就可以得到图中的算法选择决策树了。
参数自动配置算法
算法选择以后,我们需要给每种算法自动配置参数。首先,介绍恒定阈值的自动参数配置。如左下小图中的一段数据,直观来说红色区域的数值因为很罕见所以一般会被认为是有异常。通过估算这些罕见数据出现的概率,即可确定曲线的阈值。把数据看作是一组独立同分布的随机变量的值,我们可以使用 ECDF(经验累积概率分布曲线)来估计随机变量的概率分布(右下角的小图所示)。ECDF 曲线的横轴是数据值,纵轴是概率,表达的是小于等于某数值的样本比例。用户给定经验故障概率(ECDF 的纵轴),即可查找到数值的阈值(ECDF 的横轴)。我们通过 ECDF 把配置阈值转换成了配置经验故障概率。尽管不同曲线的阈值不一样,但曲线的经验故障概率常常是一致的。
实际使用中,因为历史数据样本有限,ECDF 与真实 CDF 有一定差距,直接使用容易有较多误报,我们使用了补偿系数解决这个问题。
刚才介绍了恒定阈值算法的自动配置参数过程,突升突降算法自动配置参数也是类似的,我们可以利用前文提到的空间转换公式把原始数据转换到 r 空间,然后在 r 空间上配置恒定阈值。除了 r 空间上的阈值之外,还有窗口大小 w 需要设置,不同曲线一般不会有太大区别,我们就不自动设置了。
同比算法也一样,使用 z-score 的方法把原始数据转换到 z 空间,就转换成了在 z 空间上自动配置恒定阈值参数的问题。同比天数 k 和窗口大小 w 一般也可以使用全局设置。
总结
本文从百度内部的实际异常检测场景出发,介绍了三种通用的异常检测方法,并介绍了算法自主选择策略,以及三种算法的参数自动配置策略,极大的降低了用户算法选择和参数配置的成本,有效地解决了百度内部大规模时序指标的自动异常检测的实际问题。
作者介绍:
运小博,百度高级研发工程师,从事有关运维数据分析相关的工作,负责异常检测系统和报警收敛等工作,重点关注时序数据分析、故障诊断等相关领域技术。
本文转载自公众号 AIOps 智能运维(ID:AI_Ops)。
原文链接:
https://mp.weixin.qq.com/s/AXhjawsINKl6cLDV1yf6fw
评论