异常检测

异常检测

说说我认为的异常

身处在每天调用量很大的业务系统的团队中,开发同学常常要关注于系统是否正常。说的简单点,就是当前调用是否正常,机器有没有Down机,又或者是用户是否可以正常的进行交易。

而以上说的这些就是我认为的异常。

检测异常最好的方式

检测异常最好的方式,我认为是每个开发同学直接盯着自己的一个接口看,TP99,TP999,错误率等等指标在每分钟,或者每秒钟是否正常,有没有陡然升高的情况,人的判断是比较准确地,但是受限于工作年限,线上处理异常的经验。并且最重要的,人还是需要休息嘛!所以需要机器替代人做这件事情。让机器帮助人做这件事情。

数据的分类

说到异常检测,就要了解我们需要对什么来检测异常,当然这句话是废话啦,身处于业务系统中。我们就要对业务数据做一些异常检测,那就必须将业务数据分为几类,目前我们接触到的业务数据有如下几种:
机器指标数据(CPU,Memory等)、接口性能数据(AVG,TP99等)、业务数据(下单量,交易成功数等)、

机器指标数据

机器指标顾名思义就是,关于机器的一些指标数据,例如CPU占用、MEMORY占用、网络带宽占用,因为我们的服务肯定是部署在某台机器上的,这些机器的相关指标,会直接影响到我们服务运行的状况。

性能数据

性能数据顾名思义,就是业务系统的吞吐量相关的数据,例如我们常常说的QPS(每秒请求数),AVG(平均响应时间),失败率(分钟失败率),MAX(分钟最大请求时间),TP90,TP95,TP99,TP999等。

业务数据

业务数据,顾名思义就是反应业务上面的一些指标了,对于一个交易系统来说,分钟交易数。对于一个订单系统来说,订单交易数。都是一个业务数据,在一个访问量均匀的系统来说(每天访问系统的用户基本上是有规律的)这些数据也是有规律的,这些数据可以反映出来系统的健康状况。

数据分类与异常检测方式分析

数据分为性能数据和业务数据,当然针对不同的数据,检测异常的方式肯定也不是特别的相同了。 下面就为大家分析一下不同的数据如何检测他的异常。

我们首先分析一下三种数据的特性:

  • 机器指标数据
    针对于机器指标数据,例如CPU.BUSY、网络流量等,我们一般的操作是设置指定的阈值,例如如果超过多少值就直接进行报警,例如Memory或者硬盘占用,Swap占用,超过一个指定值的时候就要进行预警了。都是可以用数值进行衡量的。

  • 性能数据
    性能数据的话,包括AVG,失败率,MAX,TP系列的指标当然是越小越好了,一般这些数据都是稳定的,例如平均接口的响应时间,在调用量正常的情况下是稳定的,TP系列的数据也是相对稳定的,失败率正常是维持在0左右。
    如果接口或者某段代码执行的流程出现问题后,这些数据就会猛然提升,例如失败率一直是0,突然程序发生问题,那么失败率一定是会陡然升高的。AVG和TP系列的指标也是相同的效果。

  • 业务数据
    业务数据,业务数据常常是和业务场景绑定的,例如团购相关的业务,周末肯定数量会比平时多很多。例如导航相关的业务,可能周末也会升高。外卖相关的业务会在中午和晚上两个吃饭的点数量偏高。
    这些业务数据,会和一定的现实情况绑定,有升有降,没有一个简单的办法去判断业务是否异常。
    例如一种简单的情况,一个电商系统,会有很多的折扣活动,每一种活动在后台的业务系统对应不同的规则,如果系统异常的时候,可能只会导致某些折扣活动发生异常,而不会一下全部影响所有的业务数据。这种就是业务数据异常检测的一个难点了。

异常检测方式

上面一节已经分析了异常的数据,下面介绍一下针对于不同的异常数据,对应的检测方式。

机器指标数据

像文章之前提到的机器指标的数据一般可以直接使用阈值进行异常检测,

阈值判断

需要检测的指标 > 指定的阈值

满足上面的公式则认为是异常点。

性能数据

针对性能数据,这种陡然升高的数据我们就可以认为就是异常数据。
例如某个时间点,失败率陡然上升了,这个时候就要引发我们的注意,了解一下是网络抖动(基本上没见过啥因为网络抖动产生的异常)还是依赖服务(DB,MQ)导致的异常。

四分位检测

针对于此类异常,一般使用四分位检测算法。简要说明一下四分位算法,四分位算法主要依赖于4分位数,
根据四分位查来判断数据是否异常。

IQR(四分位查也叫四分位距) = Q75% - Q25%

一般通过几倍的四分位距判断数据是否异常,例如一个数据已经大于3倍IQR + Q25% 则可以认定他是一个异常点。

具体操作方法,会在后期的系列文章中体现。

孤立森林-Ioslation Forest

使用孤立森林进行异常检测,孤立森林的检测方式。
简单说明下:主要在于在少量数据的情况下,构建一颗树型结构,按照数据大小,进行树的左右分布,直到数据分布到子节点。异常点的数据因为存在的特别少量,所以会被快速的分配到叶子节点,只要找出小于平均叶子几点路径的可以认为就是异常点了。

孤立森林

s(x,n)就是记录x在由n个样本的训练数据构成的iTree的异常指数,s(x,n)取值范围为[0,1]。欧拉常数值为0.5772156649。

对于s(x,n):
如果分数越接近1,其是异常点的可能性越高;
如果分数都比0.5要小,那么基本可以确定为正常数据;
如果所有分数都在0.5附近,那么数据不包含明显的异常样本。

具体的操作方法,会在后期的系列文章中体现。

业务数据

业务数据相对于机器指标数据和性能数据,检测异常的方式比较复杂,不只是一个固定的指标就可以衡量数据是否正常。而且数据基于不同的业务场景,例如团购是周末单量的,例如电商,可能是晚上单量比较高,例如直播系统也是晚上的观看用户比较高,数据是分时段的,而且有明显的业务高低峰。在不同的时间可能有不同的阈值。并且可能在节假日的时候有明显的流量区别。

根据业务数据,我们需要采用不同的异常检测算法。

首先我们要有一个前提:

业务数据是按照时间顺序记录的一组数据,其中观察的时间可以是年份、季度、月份或其他任何时间形式。

我们要想检测业务数据的异常状况,就需要对未来的业务数据做出一个预测,通过判断预测值与实际值是否相符的(上下浮动多少)的方式来进行检测异常。

常用的预测方法:

  • 简单算术平均值
  • 双指数平滑(Holt-Linear)
  • 三指数(Holt-Winters)

基于指数平滑的异常检测

通过使用多个具有相同特性的时间段,通过双指数或三指数的预测算法预测下一个周期的数据。计算数据的方差,通过K-Sigma的算法判断下一个周期的数据是否在K-Sigma之内,从而判断是否为异常

预测数据 - 真实数据 <=> K-Sigma 

后期有系列文章

基于移动均值的方式的异常检测

移动均值的检测方式,主要应用于在1:N,这种场景,例如我们有用户的入口数据,用户请求APP的数据,系统的转化率基本上是一个不怎么变化的值(如果是稳定系统),那么我们可以通过,请求数*转化率,来判断用户下单数。如果某些场景下,部分业务系统有问题了,某些优惠活动出现系统BUG,无法计算优惠。这样请求数不会改变,但是单量就会改变,此时请求转化率会降低很多。通过降低的数值我们可以判断异常。

请求量 * 转化率 - 真实数据 = 差值

差值采用K-Sigma算法进行异常检测。

后期有系列文章

基于相关度的方式进行异常检测

对于有指定转化率的方式可以使用移动均值的方式,但是在不同时间段转化率不同的情况下,则不能使用移动均值的方式进行异常检测了,这个时候就需要使用,相关度的方式。主要是看两条曲线的相关度分数。

使用相关度公式:


image.png

根据相关度的分数进行异常检测。

后期有系列文章

基于角度的异常检测

如果两条曲线强相关,例如用户访问某个接口直接转换为用户单量,则我们只需要进行两个数据的角度偏移就可以判断数据是否异常了

image.png

这样如果一个数据上升一个数据下降则夹角会非常大,可以快速了解到数据是否正常。可以通过tan等数据进行异常判断

此处只是一个想法

变点检测

变点检测,主要应用于与基于角度的异常检测类似,主要也是使用角度的方式来进行异常判断,只不过不需要另外一条参考线,变点检测主要是看单条曲线上的角度变化(只适用于平滑,数据量大的)情况。

image.png

三种曲线的曲线夹角不同,当夹角越小的时候说明变化抖动越加的明显。

基于STL的异常检测

一个基于时间序列的数据可以被分解为:

加法模型(季节性变化不明显):

时间序列(Time Series) = 季节数据(Seasonal) + 趋势数据(Trend) + 噪点数据(Random | noise)

乘法模型(季节性变化明显):

时间序列(Time Series) = 季节数据(Seasonal) * 趋势数据(Trend) * 噪点数据(Random | noise)

将公式转换:

噪点数据 = 时间序列(Time Series) - 季节数据(Seasonal)(可得) - 趋势数据(Trend)(可预测);

这样我们只要判断噪点数据是否在可以接受的范围之内就可以判断数据是否异常了。

后期有系列文章

需要注意

缺点补全

对于异常点的数据,我们需要进行去除,防止在下次计算中,异常点的数据对我们的数据有影响。

而去除后,需要对数据进行补全处理,这个时候就需要运用缺失值处理了

采用:插值法,均值法或中位数进行缺点补全。

人工反馈

有些异常情况,例如某些情况下的数据,肯定会有异常的情况,例如我去外卖上面买东西,但是那个时间点外卖店铺关门了,这个时候是由于既定实时导致的单量下降,此时需要把这个点的数值进行人工反馈。由人工来进行判断是否需要报警。

写在最后

以上是目前的一些个人在工作中的总结和一些个人的想法,接触异常检测方面的时间较少,有些专业名词可能不是很对,希望同学可以指正。

后续有时间的时候会继续把上面的相关算法计算方式补全。

你可能感兴趣的:(异常检测)