篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在实际场景中使用异常检测?阿里云Prometheus智能检测算子来了相关的知识,希望对你有一定的参考价值。
异常检测作为智能运维(AIOps)系统中基础且重要功能,其旨在通过算法自动地发现 KPI 时间序列数据中的异常波动,为后续的告警、自动止损、根因分析等提供决策依据。那么,我们该如何在实际场景中使用异常检测呢,而异常检测又是什么,今天我们就进行一次深入讲解。
作者|梵登、白玙
审核&校对:白玙
编辑&排版:雯燕
背景
异常检测作为智能运维(AIOps)系统中基础且重要功能,其旨在通过算法自动地发现 KPI 时间序列数据中的异常波动,为后续的告警、自动止损、根因分析等提供决策依据。那么,我们该如何在实际场景中使用异常检测呢,而异常检测又是什么,今天我们就进行一次深入讲解。
什么是异常检测?
在一切开始前,我们首先需要了解什么是异常检测。异常检测是指从时间序列或者事件日志中,去识别出不正常的事件、现象等。我们这里讲的异常检测特指时间序列的异常检测。通过对时间序列的值大小,曲线形态等进行综合判定,可以发现曲线异常点。异常的表现一般是指时间序列发生了不符合预期的上升、下降或者波动。
举例来说:某台机器的内存使用率指标一直在 40% 左右的水位波动, 突然飙升至 100%;某个 Redis 数据库的连接数正常水平一直在 100 数量左右, 突然发生了大规模的下跌至 0 的现象;某个业务的在线人数在 10 万左右波动,突然下跌到了 5 万等等。
什么是时间序列?
时间序列是指一组按照时间发生先后顺序进行排列的数据点序列,通常一组时间序列的时间间隔为一恒定值(如 1 分钟、5 分钟)。
当前开源 Prometheus 是如何做异常检测的?
目前开源版本的 Prometheus 检测能力还是基于设定阈值规则方式进行,而这种依赖阈值设定的方式就引出了以下问题。
常见问题
问题 1:面对数以万计的指标数量,如何快速又合理的完成检测配置?
由于不同类型指标的含义差别大,对应设定的合理阈值也不太一样。哪怕是同一种类型指标,由于业务状态不一样,往往不能用相同阈值。因此,在配置阈值时,运维人员需要根据对应的业务情况去配置自认为合理的阈值。由于运维人员认知水平和工作经验存在差异,因此不同人员配置的阈值也存在差别。其次,很多指标没有明确合理的范围定义,这导致很多阈值配置都是“拍脑袋”确定的,随机性比较强。
举例来说:某在线人数指标, 必须仔细观察分析历史指标曲线的数值分布和变化趋势,才能设置出合理的阈值。
问题 2:随着业务的演化,如何进行检测规则的维护?
对于相对稳定的业务,业务指标长期处于稳定状态,这种情况下配置的阈值可以发挥比较长时间作用。但对于时刻变化的业务, 伴随业务的不断演化,指标的水位和走势也是在不断变化。这些变化很容易导致一开始设定的阈值检测,经过一段时间则不太满足检测现状。这时候则需要运维专家定期核查检测阈值是否还符合当前检测需求,对不合理的配置进行维护与修改。因此,静态阈值方式存在着维护成本高的问题。
举例来说:某 IO 吞吐量一开始稳定在 1 万的量值附近波动,一开始设定了检测阈值为超过 2 万则告警。但随着业务发展,IO 吞吐量已稳定在 2.5 万左右,这时候一开始设定的阈值就导致了源源不断的告警叨扰。
问题 3:数据质量不佳如何解决?
数据质量不佳表现为几种具体现象:采集延迟大、数据缺失值多、数据毛刺点比较多(反应在曲线上则是不够平滑)。对于前面俩种, 更多的是从采集、聚合侧进行针对性优化。ARMS-Prometheus 持续在采集能力进行优化。而对于数据毛刺点很多的数据质量问题,静态阈值方式无法有效的规避。而在 ARMS- 托管版 Prometheus 的智能算子中, 我们则针对多毛刺点进行了有效的识别,保证了毛刺点不会形成无效告警, 减少用户侧/运维侧形成叨扰。
阿里云 Prometheus 监控是怎么解决这些问题
面对以上问题,阿里云 Prometheus 监控的检测配置能力除了支持原生的设定阈值检测方式,全面新增支持模板设定检测阈值方式与智能检测算子方式。
业务价值 1:高效高质量的告警配置
(1)针对明确的应用场景配置检测规则,阿里云 Prometheus 监控提供成熟的告警配置模板化,用户无需人工设定阈值, 只需要选择对应的模版即可。
例如:机器指标场景下, 配置“机器指标的 cpu 使用率 >80%”的模板。模板的方式解决了配置中明确异常且业务比较稳定的应用场景痛点。
(2)针对不明确的指标场景或不好设定的业务指标场景,则推荐使用智能检测算子功能。
例如需要对某在线人数指标设定阈值, 这时需要花费很长的时间观察历史曲线状态才能配置出合理的阈值。这种场景下用户可以直接选择智能检测算子。
业务价值 2:自适应追踪业务变化,大大降低检测阈值维护成本
阿里云 Prometheus 监控的智能检测算子功能,通过设定参考历史数据长度的参数,模型可以自适应的追踪指标趋势的变化,无需人工定期去审查配置规则。
业务价值 3: 对于质量不佳,缺失值/毛刺点过多的指标也可以实现智能检测
在智能检测算子功能中, 如果历史数据出现了缺失,算法可以线性插值,多项式插值等多种方式,自动填补缺失值。
对于不平滑的指标曲线检测,智能检测算子也自适应的选择针对该场景的最优模型进行检测,保证整体的检测效果。
如何应用在具体业务场景里
水位突增/突降型指标:某业务的 qps 指标
在业务开始设定阈值时, 通过观察很有可能设定阈值不超过 150。但随着业务迭代,qps 指标也会发生各种各样的变化。从指标上则表现为:出现阶段性的突增至某个值,然后平稳的状态。这种情况下,设定的静态阈值很难持续满足检测需求。另外一方面, 稳定情况也会出现突发的下跌, 只设置上限的静态阈值是检测出这种下跌情况的。这种情形下, 智能检测算子则可以自适应的跟踪业务水平的变化,智能识别业务的突增或突降。
周期性的指标:
在指标画像模块,如果识别出当前的指标具有一定的周期,则会从中提取出对应的周期值、周期偏移值, 以及整体趋势曲线。在原始的时间序列去除周期性、趋势性后,利用残差进行异常检测。以上图的周期指标为例, 11.30 分左右的周期与其他周期出现明显差别。传统静态阈值很难去解这类场景下的检测问题, 而利用智能检测算子,则可以识别出该种异常。
趋势破坏型的指标:
此外,还有一种常见类型的指标异常是,在某一阶段内, 指标一直呈现上升(或者下降)趋势。在某一个节点出现突发性的趋势破坏,局部呈现了和整体趋势不一样。这种异常类型也是很常见的,但是静态阈值很难设定来解决这种情形。而智能检测算子则针对这种类型可以进行准确了的识别异常。
最佳实践
阿里云Prometheus监控内使用流程
目前阿里云 Prometheus 监控已经支持智能检测算子功能,只需登陆 ARMS-Prometheus/grafana,输入对应的 PromQL 即可。
算子定义
"anomaly_detect": {
Name: anomaly_detect",
ArgTypes: []ValueType{ValueTypeMatrix, ValueTypeScalar},
ReturnType: ValueTypeVector,
},
输入:指标的时间序列,类型为range vector;检测参数,使用默认的3即可
输出:异常返回1, 正常返回0
使用 case:
anomaly_detect(node_memory_free_bytes[20m],3)
- 输入的必须是 range vector,因此需要在指标名称后增加[180m], 时间范围默认选择 180m,参数默认选择 3
- 如果先进行了其他聚合函数操作,则需要[180m:],使之变为 range vector,如下:anomaly_detect(sum(node_memory_free_bytes)[180m:],3)
使用示例:
step 1: 登陆到 ARMS-Prometheus 或 Grafana 中选择对应的 Prometheus 数据源
选择对应的数据源:
step 2: 选择指标, 并查看
step 3: 输入异常检测算子
关于 Prometheus- 智能检测算子
阿里云 Prometheus 监控智能检测算子,总结业界数十款领先的算法方案实践设计而成。针对常见的指标类型建立了指标画像,并自适应的选择最佳模型去进行检测计算。每一条指标数据输入模型后, 模型首先会对当前的指标建立指标画像,包括平稳性,抖动性,趋势性,周期性,是否为特殊节假日/活动等。根据这些画像特征构建之后, 模型自适应选择最优一种或者多种算法组合来解当前的指标检测问题,保证了整体效果最优。目前已经支持的功能包括:突增检测、毛刺检测、周期识别(识别周期性、周期的偏移)。
通过阿里云 Prometheus 监控中集成智能检测算子, 我们希望给用户可以提供开箱即用、持续迭代更新的智能检测服务。目前用户可以在阿里云 Prometheus 监控中查看并使用智能检测算子,而基于 ARMS 的原生配置智能检测告警功能和 Grafana 动态展示将在近期推出。
AIOps中异常检测的简单应用
异常检测是AIOps领域中最为常见也是十分重要的一个问题,它将直接影响到报警产生以及后续所有自愈动作的开展。公司内部运维数据众多,因此对于异常检测方法的实时性,准确性有很高的要求。异常检测作为运维领域的通用场景,已经存在很多的方法模型可以使用。但是各个方法之间的异同,不同方法针对不同场景该如何匹配还是值得使用者认真考虑一番。本次分享将详细介绍常见的一些异常检测方法的优劣以及使用场景,并利用一个实际的场景作为例子,展示360在大数据背景下是如何利用异常检测模型进行网络监测的。
异常点也称为离群点,一般由于数据来源于不同的类型,噪声或者收集时的误差所产生。所谓异常检测,就是利用某些方法将异常点找出来。异常检测的应用有很多,这里只做简单的举例,例如在数据预处理方面可以用于去噪,在运维领域则产生报警,在金融和安全领域中,异常检测可以帮助判断数据波动以及是否受到攻击等等。
固定阈值法是比较常见的一种异常检测方法,一般由业务人员针对不同的业务场景,设置一个固定的阈值。当观测值大于(或小于)阈值时则判断观测值是异常的,否则认为是正常的。该方法的优点在于简便,缺点在于过于依赖阈值设置者的经验,场景适配性低,不够通用。
下图给出了固定阈值方法判断异常的效果图,图中阈值设置为90,大于90的点视为异常点。可以看出只有少数点被检测为异常点,会出现漏报的问题。
这个方法比较简单,这里就不详细介绍了,该方法与固定阈值方法的优缺点相同,这里只给出利用3sigma进行检测后的结果,如下图所示。可以看出利用3sigma方法只能找出一个异常点,漏报问题严重。
统计方法整体的优点在于计算速度快,模型简单,易于实现。缺点在于模型对场景适配性不足,模型不够通用,一般只能进行单一维度的异常检测等等。
首先计算过去N天(一般是14天)的同比振幅最大值max_amplitude,其次计算当前的观测点与过去一天的同比值value,如果value>thresold*max_amplitude则认为当前点是异常的,反之则认为是正常的。该方法的优点在于利用了数据的周期性,规避了数据曲线自身周期性突变的情况。缺点在于周期性突变的时间必须重合,否则容易误警。
下图给出了同比振幅检测的检测结果,后两部分之所以被视为异常是因为这两个段变化相对于之前的周期更大,当然这个判断的结果是可以通过阈值进行调整的。
EWMA方法可以视为一个简单的预测方法,他的主要想法是时间越近的数据权重越高,时间越远的数据权重越小。该方法的具体表达式如下所示,运用该方法进行异常检测时,首先对当前点计算EWMA值,然后利用3sigma方法进行异常点的判断。这个方法的优点在于容易检测到突变型异常,并且对于一个异常较短时间后发生的另一个异常的检测有较好的效果。缺点在于对于渐进型而非突变型异常检测能力较弱,异常持续一段时间后可能被视为正常。下图展示了使用EWMA方法进行异常检测的效果,可以看出整体效果还是很好地,对于孤立的异常点可以好的检测出来。
环比点检测方法首先计算待测点于过去30分钟的历史值的增幅比率,然后统计增幅比率超过增幅阈值的个数,如果异常数超过了阈值则认为是异常点。该方法的优点在于可以有效的检测出单点突增以及渐进型异常,缺点是异常持续一段时间后可能被判断为正常。下图展示了环比点检测的检测效果。
环比振幅检测方法需要计算过去10分钟与过去1h均值的振幅比率,并于阈值进行比较,超过阈值则认为是异常,否则认为是正常点。该方法的优点在于对于持续一段时间的异常检测比较明显,可以检测出短期的持续型异常,缺点在于容易掩盖单点突增的异常。下图展示了环比振幅检测的检测效果。
K_test检测通过判断两组数据是否来属于同一分布进行判断待测点是否是异常点。在进行K_test检测时首先将数据分成两部分(最近10分钟数据作为一组,10分钟前1小时数据为一组),其次对两组数据进行Kolmogorov-Smirnov检测(判断两组数据是否服从同一分布),如果两组数据服从统一分布,那么待测点是正常点;如果两组数据不服从统一分布,那么需要对近10钟的数据进行平稳性检验,如果不平稳则说明待测点是异常数据。K_test检测对于持续一段时间的异常检测有比较好的检测效果,容易忽略单点的突变现象。下图显示了K_test检测效果,可以看出异常刚刚产生时可以很快检测出,但是一段时间后,检测效果就不明显了。
聚类方法中能够进行异常检测的算法不多,DBSCAN算法是其中比较优秀的一种。DBSCAN算法通过邻域距离和最小包含点数两个参数,可以找出数据中的核心点,边界点。而既不是边界点也不是核心点的点即为噪声点。核心点,边界点的概念这里不做解释,请自行查询。本分享中对于DBSCAN算法的原理我就不做详细的说明了,这里给出DBSCAN算法原始论文地址,有需要的同学可以自行阅读。https://www.aaai.org/Papers/KDD/1996/KDD96-037.pdf
下图给出DBSCAN算法异常检测的效果,可以看出检测的效果还是很好的。
IForeast算法是周志华老师设计的一种异常点检测算法,该方法同过利用数据构建iTree,进而构建iForest,是一种无监督的检测方法,具有很好的效果,具体的原理见:https://cs.nju.edu.cn/zhouzh/zhouzh.files/publication/icdm08b.pdf。
IForeast算法的优点是无监督模型,算法稳定,可以进行高维度检测,但是算法不适用于特别高维的数据,由于每次选取数据空间都是随机选取一个维度,建完树后仍然有大量的维度信息没有被使用,导致算法可靠性降低。下图展示了IForeast算法的检测结果,可以看出该方法的检测效果还是比较好的。而且由于算法集成在sklearn包中,可以将训练好的模型保存为文件形式,每个模型大约1~2M。
下面我通过一个实际的场景来具体的说明一下,我们是如何利用异常检测算法来进行流量异常判断的。
网络质量问题一直是一个限制产品质量的瓶颈问题,对网络质量的探测与及早预测能够有效的解决网络延迟等问题,从而极大的提高用户的体验。为了检测网络质量,我们以CDN机器模拟用户,向公司拥有的所有vip发送消息,采集平均延迟(avgdelay)和丢包率(loss)两个网络数据作为评价网络质量的指标,通过对这两个指标的判断从而实现外网质量检测的目的。整体的外网质量监控流程如下图所示,我们原始的策略是:loss>0.5认为是异常,对于avgdelay不做判断。改进策略是:利用异常检测算法检测avgdelay,不同的链路根据自身历史数据变化分析计算,阈值不同,实现高敏度差异性检测。
实时性强:场景覆盖了多个核心业务的全部2K多个目的vip,源CDN机房覆盖5个ISP,25个省市,总共超过10W+的链路需要判断。这些链路需要每分钟进行一次数据采集并及时进行异常检测,所以对于实时性的要求很高。
解决方案:利用Redis缓存一部分数据(最近2小时共计120点),从而节省了从数据库中获取历史数据的时间,某些模型可以提前训练好并加载在内存中,以备使用。
单一模型判断不准确:前面介绍了很多异常检测方法,但是在实际应用时发现某些模型不适用于场景,而且仅用单一模型进行异常检测精度很低。
解决方案:多模型进行组合判断,这里采用比较简单的加权众投决策。根据不同模型的检测效果确定模型的权重。
链路众多,模型存储和加载困难:刚刚说过此场景中需要判断10W+链路,模型需要预先训练好并加载在内存中从而减少计算的时间。就IForeast模型为例,一个模型大约需要1~2M,10W+模型需要10~20G。模型所需的内存巨大,并且不可能全部加载到运行内存中。
解决方案:针对链路和数据众多,模型数量巨大的问题,我们希望通过对链路进行聚类的方式进行降维,从而减少所需训练的模型数量。
针对链路众多,数据量大,检测实时性强的问题,我们考虑利用Redis中pubsub实时性强的特点加以解决。实际的解决方案如下图所示,接收端每分钟对10W+的链路数据进行采集,并存入Redis中;Redis预先保存着119位数据,接到数据后从而保证每个链路存在120位数据,针对缺失数据用null补充;当收到数据后将全部的120位数据以参数的形式传给异常检测模型中进行检测,从而抱着了实时的产生异常报警。
下图展示了分别用环比振幅检测,环比点检测,孤立森林算法以及三种方法按照一定权重融合后的组合模型对某链路进行的异常检测效果。从图中可以明显看出单一模型各自都有一些异常点无法判断出,组合模型对于异常点的判断更为全面。当然,再计算模型阈值时,我们假定数据中异常点的比率为10%,这个数值可能不是很合理,这需要根据实际场景进行调整。
前文提到过,场景存在10W+链路,一个模型大约需要1~2M,如果每个链路都需要进行模型训练,那么需要10~20G的内存,这个存储量比较大。因为我们决定对链路进行聚类,从而起到降维的作用。常见的聚类模型有:DBSCAN模型,Kmeans模型以及MiniBatchKmeans模型,下面分别介绍一下他们的特点以及在此场景中应用的效果。
DBSCAN模型:DBSCAN模型的优点在于不需要设定聚类个数,模型会自动将数据分为多个类别。这个特点其实在这个场景中是很有用的,因为我们不知道应该将链路聚为多少类最合适。但是DBSCAN模型的缺点在于调参困难,链路众多,通过绘图等方式人工调参效果很差。因此我选择用差分进化算法帮助寻找参数。但是调参的速度很慢,因此放弃这种方法。
Kmeans模型:Kmeans模型的优点在于参数少,只需要提供聚类的个数即可,但是缺点在于聚类个数难以确定,大规模数据聚类速度缓慢(本场景预计需要2天时间),得到的是局优解,对噪声敏感。由于聚类速度慢,因此也被舍弃。
MiniBatchKmeans模型:MiniBatchKmeans模型是Kmeans模型的改进,每次不选取所有的数据进行聚类,而是每次随机选取一部分数据聚类,分批聚类的方式减少计算量,提高速度。该方法适用于大规模多特征数据聚类,本场景每次聚类平均需要7s。MiniBatchKmeans模型我在这里不做详细的介绍,我提供该模型的论文地址,有兴趣的同学可以自行阅读:http://www.eecs.tufts.edu/~dsculley/papers/fastkmeans.pdf。对于MiniBatchKmeans模型与Kmeans模型聚类偏差问题,这里我借用网上其他人的比较效果加以展示,可以看出两个模型聚类偏差不大,可以接受。
选定了聚类模型后,还有两个问题需要解决,第一是聚类模型中特征的提取与构造,第二是聚类个数的选择。
特征的构造:原始数据是某条链路过去7天的平均延迟,我在构造特征时遵循新数据权重大,旧数据权重小的原则进行特征的构造。具体的特征结构如下所示:
这里需要解释一下,avg1D(10%,90%)指的是,将最近1天的数据进行由大致小顺序排序,取最大的前10%数据以及剩余的90%的数据的平均值,作为2个特征。item数值则按照数据权重大,旧数据权重小的原则计算得来的,每天的权重依次缩小二分之一。
K值的选择:聚类个数的选择十分重要,将直接影响聚类的效果。考虑到每个模型大小约1~2M,因此将K的取值范围定为[50,150]。常见的K值选取的方法有两种:
手肘法,即依次计算不同K值的聚类后的sse,并绘制K-sse曲线,如果形成下图类似的手肘形式,那么就取拐点值作为K值,因此下图中应该取K=4。
最优值方法,聚类时希望类内距越小越好,类间距越大越好,因此计算value作为衡量聚类效果的指标,value具体表达如下。可以看出value值越小则聚类效果越好。
针对这两个方法,我分别遍历K的不同取值,并绘制了K-sse曲线以及K-value曲线,如下所示。可以看出K-sse曲线并没有显示出手肘形式,不存在拐点。因此我们选用最优值方法,选择value最小值对应的K作为聚类个数,此处K=78。
下图展示了分别用环比振幅检测,环比点检测,孤立森林算法以及三种方法按照一定权重融合后的组合模型对某链路进行的异常检测效果。可以看出孤立森林算法检测出的异常点明显比其他模型检测出的多,因为该模型是适用一类链路的平均值进行训练的,因此对单一链路效果略差。但是融合模型规避了这一问题。
最后,我想写一点关于异常检测的常见问题,作为结束。异常检测作为AIOps领域的通用场景,被广泛的应用与研究。本文中提到的一些方法都比较简单,当然还有很多复杂而且优秀的方法,本文没有涉猎。实际应用者总会在算法模型的选择上纠结,我也常常对此产生困惑。所以首先,我便来聊一聊模型的选择问题,这仅仅是我自己的看法,仅做参考。我觉得作为算法工程师,我们应该对于复杂的模型有自己的追求,不停的研究准确度更高的模型,不断地开阔自己的思路。但是精度高的模型往往跟随着复杂度大,训练速度缓慢的问题,所以研究是一方面,但是落地又是一方面。针对实际场景应该选择最适合的方法,即使最简单的固定阈值方法最有效,也不要为了AI而AI,要摒弃模型越高大上越好的想法,作为聪明的人应该做聪明的事。应该思考如何将高大上的模型适配于当前的场景。
除了模型的选择,我还想说一下人工标注以及人工经验对于AI的重要程度。提到人工标注,可能常见于分类等有监督模型中,对于无监督模型,因为对于数据的要求中可以没有标签,因此标注就不那么常见了。但是在实际的应用中,我发现,其实人工标注不论在有监督还是无监督的模型中都是极其重要的。就以本文所提的异常检测模型,都是一些无监督的模型,但是即使是无监督的模型,也需要通过阈值对比才能产生结果,阈值的训练是很复杂的,针对不同的场景,不同的数据源,阈值也不同。因此,如何提高异常检测的准确度,选择优秀的模型是一个方面,还有就是可以通过人工标注的方式,对AI判断出的异常加以修正,从而反馈模型,起到提高检测质量的目的。人工经验也是很重要的,并不是有了算法模型就可以把人工经验抛到一边,否则就是一种浪费。我们利用人工经验帮助我们进行数据的筛选,将过于异常的数据筛选出去,从未保证数据的跨度较小。也可以利用人工经验辅助算法,从而提高检测的准确性。
Q:
这几类算法中,是否有适用于趋势类的告警的,检测单个曲线的异常点(突增或者突降)用什么算法比较好?
A:趋势的话可以用k_test,环比振幅检测应该都是有效的,但是这个还是要看具体的场景,根据不同的场景和数据,选择模型,并调整最终的阈值。
Q:
今天的算法只是有数字上的检测,如果是文字上的检测这些方法是否还适用呢?
A:针对多维的异常检测,前面的一些统计方法就不适用了,但是对特征进行较好的提取的话,iforeast方法和DBSCAN模型应该有效。
Kubernetes入门与实战培训将于2020年2月28日在北京开课,3天时间带你系统掌握Kubernetes,学习效果不好可以继续学习。本次培训包括:Docker基础、容器技术、Docker镜像、数据共享与持久化、Docker实践、Kubernetes基础、Pod基础与进阶、常用对象操作、服务发现、Helm、Kubernetes核心组件原理分析、Kubernetes服务质量保证、调度详解与应用场景、网络、基于Kubernetes的CI/CD、基于Kubernetes的配置管理等等,点击下方图片或者阅读原文链接查看详情。
以上是关于如何在实际场景中使用异常检测?阿里云Prometheus智能检测算子来了的主要内容,如果未能解决你的问题,请参考以下文章
阿里云异常网络连接-可疑WebShell通信行为的分析解决办法
AIOps中异常检测的简单应用
如何通过云效流水线扩展代码检测
EasyNVR级联阿里云设备通道状态显示异常是什么原因?
带你读论文丨异常检测算法及发展趋势分析
带你读论文丨异常检测算法及发展趋势分析