自动化运维系统中有一项功能就是各种指标的异常报警,目前系统采用的是恒定阈值的办法(就是几个人拍脑袋想出来的),这样带来的问题主要有两个:首先是 每个现行系统的指标参数比较多,每个指标都拍次脑袋,所有的阈值没设定完 脑袋就已经先拍破了
;其次,这样定出来的阈值不是报警太频繁就是出了问题也不报警,没法做到自适应。
基于以上的原因,准备给系统的报警子系统添加异常数据检测。因为是工作中的项目,出于保密性,略去所有数据集的相关图表,只表述核心算法思想和结论。
==========================俺是可爱的分割线===================
一、算法选择
由于只是提供一个报警功能,至于到底要不要去处理最终还是需要工程师来决定,所以决定暂时不需要很复杂的算法,经过权衡选取两个比较简单的算法作为候选
1. 箱型法,即将数据(这里都是一维数据)先按从小到大顺序排列,然后算出一分位数q1、三分位数q3,然后计算最大估计值(因为系统不关心最小估计)如下图所示:
利用之前的数据作为样本集,算出最大估计值。做检测的时候,取连续一段时间内数据同最大估计值做比较,如果超过90%的数据都大于改值则判定异常报警。
2. 莱茵达法则,先计算样本集的均值 avg和方差 std,测试集中计算|xi - avg | > 3 * std,同样连续一段时间内的取样值超过90%的数据大于这个范围则判定异常予以报警。
二、 算法测试结果
1. 取系统8月份的数据作为样本集,分别计算某个指标的集的q1,q3,avg,std
2. 取系统9月份的数据作为测试集,分别按两个算法计算报警的次数和时间段
3. 箱型法报警结果,分别在三天的不同时间段给出了总共12次报警;莱茵达算法,在三倍标准差的情况下没有给以报警,调整到1.5倍标准差后,给出了一天的5次报警(同箱型法重合),之前的恒定阈值下 整个9月份未给予一次报警
三、结论
箱型法算出来的最大估计值作为阈值的话,相较于莱茵达法系统会比较敏感,报警的次数也好相应的比较多,如果是系统里比较重要的指标可以使用该方法,反之则可以使用莱茵达算法,根据实际需要调整k值或标准差的倍数来达到系统的敏感度。其次,在实际系统中,由于算法很简单,所以可以在每天的夜里固定时间内重新计算系统预测需要的q1,q3,avg,std(将当前时间的前30天做为样本集,这样可以降低系统的误报警率)。在后续的工作中,还需要根据指标重要程度和性质引入算法选择器(即,自动选择计算列的算法)