在Elasticsearch中实现统计异常检测器——第二部分
Implementing a statistical anomaly detector in Elasticsearch - Part 2
上一周,我们建立了一个pipeline聚合,将数千个数据点分解成少数代表性指标。 这形成了Atlas的基础,并且为实现异常检测器所做的所有重大工作。本周,我们将结束实施并生成一些有趣的图表。
我们创建的聚合被设计为在特定的时间窗口上运行:给定日期范围,它将为每一个metric发出第90个百分点的意外(surprise)值。要完全实现Atlas,我们需要随着时间的推移绘制第90个百分点值。目前这个功能仅仅使用Pipeline聚合是不可能使用的(虽然已经提出了一种“滑动柱状图”功能来弥补差距)。
替代的,我们将把责任移交给TimeLion,它非常适合这种后期处理(Timelion是一个新的{Re}search项目,在kibana内部进行流畅的时间序列操作,你可以在这里)。
假如你重新去看模拟器的代码,你将看到我们在数据生成之后运行了一查询系列 。我们以一小时的增加滑动我们的Pipeline聚合数据(窗口的大小为24小时)。我们还使用了filter_path来最小化输出,我们实际并不关心60,000个buckets。我们仅仅想要每个metric的“ninetieth_surprise”。过滤响应大大较少了网络传输。然后将值索引回Elasticsearch,以便我们稍后再对其进行统计。
我们在模拟器中提前预处理了这些值,以简化演示,但在一个真实的系统中,你可能会有一个Watcher或者cronjob每小时执行一次查询并保存结果。
Plotting 90th percentile surprise
通过上周的艰难举措,我们可以转而使用Timelion完成实施。第一个业务是降低特定指标的第90个值(the 90th values)。我们可以使用以下Timelion语法:
.es('metric:0', metric='avg:value').label("#0 90th surprise")
它将生成看起来像这样的一张图表:
那看起来很有趣!绝对有事情发生。我们来看看这张图表的含义,因为它是Atlas的工作原理:
- 上周,我们计算了每一个时间序列的“surprise”:偏离自己的移动平均线。
- 然后,我们收集了这些“surprise”值的前第90个百分位数,并且正在随着时间的推移来绘制它们。
- 实际上,这张图表显示告诉我们前面"surprise"(偏差)的变化性。
- 这个图标中大幅度的颠簸意味着数据变得更加 surprising,前第90个百分位数发生了巨大变化(上升或下降,因为我们使用绝对值计算surprise)
实际上,如果我们看到一个凸起,我们可以得出结论,基础数据已经发生了改变,以改变了我们的正常方差,可能是由于中断。这是Atlas的核心:不要看你的数据,因为它是如此的多。相反,观察偏离平均值的第90个百分位数的差异。
假如将上图表和metric #0的实际数据相比较,你将看到明显的区别:
Building the Atlas Dashboard
当然,诀窍是现在自动识别那些凸起和图表/警告。让我们开始构件逻辑。当第90个百分位数surprise是移动平均线以上3个标准差时,Atlas报警。假如你分解该问题,你将看到一些必要的组件:
- 滚动三标准差
- 数据滚动平均线
- 在滚动数据之上添加滚动标准差。这表示数据必须低于“阈值”
- 当数据冲破“阈值”时报警
首先,我们构造滚动三标准差。我们通过自定义movingstd()函数来做到这一点(参见注脚脚本,它与movingavg()函数基本相同),然后乘以3,以得到第三个sigma:
注意:我缩进了所有的查询,以使他们更加容易阅读。
.es('metric:0', metric='avg:value').movingstd(6).multiply(3)
其次,我写了一个计算数据本身滚动平均线的片段:
.es('metric:0', metric='avg:value').movingaverage(6)
最后,我们通过将这两个片段加在一起以创建“阈值”。这将创建一条在数据移动平均线以上三个标准差的线。
.es('metric:0', metric='avg:value').movingaverage(6).sum(.es('metric:0', metric='avg:value').movingstd(6).multiply(3))
现在我们有了一个“阈值”,我们可以用原始数据绘制,并看看它们如果比较:
嗯,OK。如果阈值是否工作,现在还不清楚。该图表很难阅读,一旦surprise值凸起,就会导致阈值的后续的凸起。这是因为凸起导致方差的巨大变化,滚动标准方差会上升,导致阈值本身的上升。
假如我们放大第一个凸起,我们可以看到,在滚动标准方差上升之前,第90个百分位数稍微超过阈值:
(抱歉,此图表错误标注:“metric:0”应该显示为“#0 Threshold”)
现在很清楚:我们想显示的是surprise超过阈值的时刻,并且另外忽略阈值(因为它只在第一瞬间有用)。当它超过阈值的时候,让我们显示单独的条,以替代持续的线条。 为了做它,我们构造了showifgreater()方法。这将只显示第一个系列中的数据点,如果它们大于第二个系列中的数据点(参见注脚脚本)。
.es('metric:0', metric='avg:value').showifgreater(...)
要完成我们的查询,我们仅仅希望显示大于三个标准方差大的数据(假如它突破了阈值),然后我们要显示为棒而不是线条。这组成了我们最后的查询:
.es('metric:0', metric='avg:value').showifgreater(.es('metric:0', metric='avg:value').movingaverage(6).sum(.es('metric:0', metric='avg:value').movingstd(6).multiply(3))).bars().yaxis(2).label("#0 anomalies")
这产生了更好看的图表:
最后让我们加回数据本身,这样就可以进行比较了:
.es('metric:0', metric='avg:value').label("#0 90th surprise"),
.es('metric:0', metric='avg:value').showifgreater(.es('metric:0', metric='avg:value').movingaverage(6).sum(.es('metric:0', metric='avg:value').movingstd(6).multiply(3))).bars().yaxis(2).label("#0 anomalies")
瞧!我们已经实现了Atlas!完整的面板包括每个metric的图表,以及显示中断创建时的图表(你显然不会在生产环境中使用,但对于验证我们的模拟数据是有用的):
Analysis of anomalies
如果你通过中断图表(左上角)进行操作,你将至少在一个metric图表中找到相关的异常,通常几个在同时。令人鼓舞的是,异常被标记为所有类型的中断(node,query,metric)。注脚包含了一个中断的列表和它们的大小,以让你了解影响。例如,一个“Query Disruption”持续了三个小时并且仅仅影响总共500个查询中的12个(2.4%)。
在图表中看到的一个现象是一小段时间保持在高位的凸起。这部分是由于中断的持续时间,有些持续了几个小时。但也有可能是由于我们上周提到的pipeline聚合的局限性:我们选择了每个时间序列最大surprise,而不是最后的surprise。这意味着在最坏的情况下,中断会延长额外的24小时,因为一旦中断从窗口上脱落,surprise才会重置。这完全依赖于选择窗口的大小,并且可以通过增加/减少窗口来改变敏感度。
这种现象不会影响的异常检测,尽管如果你尝试使用更长时间窗口,这一点变得更加明显。一旦pipeline聚合有选择“最后”的能力,这个现象应该就被解决了。
Conclusion
So,那就是Atlas,在eBay建立的一个非常简单--但非常有效--统计异常检测系统,现在在Elasticsearch +Timelion上实现了。在pipeline聚合之前,这可能是由很多客户端逻辑实现的。但是,每小时将60K的buckets流向客户端处理的前景并不诱人,pipeline聚合已经将重要的举措转移到服务器以进行更有效的处理。
pipeline聚合还很年轻,随着时间的推移,期待更多功能被添加。假如你有一个难以在pipeline中表达的用例,请告诉我们!
The end! Or is it...
“可是,等等” 你说,“这只是绘制异常,我如何获取预警”。对于这个答案,你必须等到下周,当我们实现了TimeLion语法作为观察者观察,如此你能获得email,Slack等等的自动预警,下周见!
Footnotes
- 自定义movingstd()和showifgreater() Timelion 功能能在这里找到,关闭Kibana,把该功能增加到Timelion的源码(kibana/installedPlugins/timelion/series_functions/<function_name>.js),删除优化的包(rm kibana/optimize/bundles/timelion.bundle.js)并重启Kibana。该功能现在应该可以在Timelion中使用了。注意:JavaScript不是我的特长,所以这些都不是典型的代码示例。
- 模拟中断如下。格式为格式:中断类型:开始时间-截止时间[影响 节点/查询/指标]
- Metric Disruption: 505-521 [0, 3, 4]
- Metric Disruption: 145-151 [3, 4]
- Node Disruption: 279-298 [0]
- Metric Disruption: 240-243 [1]
- Query Disruption: 352-355 [5, 23, 27, 51, 56, 64, 65, 70, 72, 83, 86, 95, 97, 116, 135, 139, 181, 185, 195, 200, 206, 231, 240, 263, 274, 291, 295, 307, 311, 315, 322, 328, 337, 347, 355, 375, 385, 426, 468]
- Metric Disruption: 172-181 [0, 2]
- Node Disruption: 334-337 [0]
- Query Disruption: 272-275 [63, 64, 168, 179, 193, 204, 230, 295, 308, 343, 395, 458]
- 在上周的文章之后,有一些关于数据本质的问题:也就是,使用正态(高斯)曲线生成数据。Atlas可以使用曲解的数据,因为现实生活中很多数据不会遵循一个很好的正态分布?我使用LogNormal曲线运行了一个快速测试,该曲线严重偏向左侧,而Atlas依旧运行良好。该Atlas论文证实了这一实验性证据。Atlas依赖于第90个surprise随着时间推移而变得正常,即使基础数据严重偏离,似乎也是如此。可能有关于Atlas在不同数据分布下行为的后续文章,假如我有时间进行实验。
原文地址:https://www.elastic.co/blog/implementing-a-statistical-anomaly-detector-part-2
转载于:https://www.cnblogs.com/benjiming/p/7147608.html
在Elasticsearch中实现统计异常检测器——第二部分相关推荐
- 在Elasticsearch中实现统计异常检测器——第三部分
Implementing a Statistical Anomaly Detector in Elasticsearch - Part 3 欢迎来到Elasticsearch建立统计异常检测器的第三期 ...
- 在Elasticsearch中实现统计异常检测器——第一部分
Implementing a Statistical Anomaly Detector in Elasticsearch - Part 1 该图显示了4500万个数据点的最小/最大/平均值(超过600 ...
- 在Elasticsearch中对 text 类型的字段进行聚合异常Fielddata is disabled,Set fielddata=true
在Elasticsearch中对 text 类型的字段进行聚合异常Fielddata is disabled,Set fielddata=true 参考文章: (1)在Elasticsearch中对 ...
- 在Elasticsearch中回测隨機(Stochastic)指標交叉交易策略
之前的文章"在Elasticsearch 中回测 RSI 交叉策略",介紹在Elasticsearch中如何回測 相对强弱指数(RSI)指标交叉交易策略.在本文中,我们将实施随机( ...
- Elasticsearch中的Zen Discovery选主流程
文章目录 背景 为什么使用主从模式? 选举算法 什么时候触发选主? 选主过程 选举临时Master 投票与得票的实现 确立Master或加入集群 选举完成 elasticsearch中的Discove ...
- 在Elasticsearch中回测阿隆(Aroon)指標交叉交易策略
我们已经讨论过如何在Elasticsearch 中回测" RSI 交叉策略"和 随机(Stochastic)交叉策略,在本文中,我们将实现阿隆(Aroon)交叉策略,并将其性能与上 ...
- 在Elasticsearch中回测超级趋势线(Supertrend)交叉交易策略
我们已经讨论了好几个单一指标交易策略,其中简单的相对强弱指数(RSI)交易策略取得的利润最高. 在本文中,我们将使用 Elasticsearch 实现超级趋势线(Supertrend)交叉交易策略,并 ...
- 理解Elasticsearch中的桶聚合(Bucket aggregation)
0. 前言 Elasticsearch除了在搜索方面非常之快,对数据分析也是非常重要的一面.正确理解Bucket aggregation对我们使用Kibana非常重要.Elasticsearch提供了 ...
- 图解Elasticsearch中的_source、_all、store和index属性
为什么80%的码农都做不了架构师?>>> Elasticsearch中有几个关键属性容易混淆,很多人搞不清楚_source字段里存储的是什么?store属性的true或fals ...
最新文章
- 网吧母盘制作(精华)
- C#串口通信学习笔记
- a partial surjection的题库
- C++Quick sort快速排序的实现算法之二(附完整源码)
- [转载] 什么是istio 官网内容
- python 爬取豆瓣top100电影页面
- 递归的经典例子 java_java递归算法经典实例
- lua 常用数据类型总结
- arc diff 指定版本号_marlin固件详解《个人感觉比较全》
- macOS - 安装 swig 、PCRE
- 车辆违章查询接口,获取支持城市参数接口示例
- 比较好做的计算机毕设,大学几年快结束了,计算机毕设到底该怎么做?
- java opengl 话正方形_OpenGL绘制正方形并让其移动
- Error: Can't find Python executable python, you can set the PYTHON env variable.解决办法
- 判断是否是回文字符串两种方法
- uiautomator2,一款比appium还好用的app自动化测试框架
- canvas实现炫酷的一键抠图和背景替换
- W25Q128华邦Flash调试踩坑
- JQuery datatables 详细配置以及aoColumns参数
- 「经济理财」跟简七学理财之理财训练营(上)
热门文章
- PS制作恐怖逼真滴血文字
- *p++、*(p++)、++*p、++(*p)、(*p)++
- ruby非阻塞式socket编程--写飞信客户端的经验总结
- 计算机win10无法正常登录系统,win10系统无法登录战网的四种解决方法
- 码代码微信号今日上线,为互联网同仁提供最前沿咨询
- Ghost XP SP3 纯净标准版 V2013.10
- abap中ROUND 函数使用方法
- 简短冷段子、冷笑话笔记
- Google Play 政策更新提醒与重点解读 | 2021 年 10 月
- MySQL中的日期时间类型与格式化方式