Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 622|回复: 0

在Elasticsearch中实现统计异常检测器——第二部分

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-9-7 10:58:04 | 显示全部楼层 |阅读模式

    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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-27 12:33 , Processed in 0.073610 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表