https://v.qq.com/x/page/n0560jjv24y.html
概述
ES的聚合能力非常强,延迟低;而SQL相对于DSL来说有较高的抽象层次,更为大众所熟悉。在做报警引擎的时候我们发现,纯用ES难以解决https://www.3tt.net/?mod=artinfo&aid=329我们的问题,必须要在ES计算后进行第二次处理。RDL用“规则描述语言”,提供计算机辅助功能。
SQL及扩展
过滤
过滤表达式:inbyte + outbyte > 10000 AND sip = ‘192.168.0.55’
过滤表达式有基本的四则运算,并对ES支持的某些脚本添加了一些抽象函数。
ES也是基于时间线的,无论是做日志采集还是数据监控,都要指定一个时间域。我们做报警时首先要解决的就是时间模型,需要把时间模型抽象出一些函数。
过滤函数:last(5m)、last_days(3,5m)、last_weeks(4,5m)、last_weekdays(3,10m)、range(flows,[100,1000])、ip_range(sip,’192.168.0.0/24’)、date_range(…)
query_string(‘sip:[192.168.0.100TO 192.168.0.200]’)
以上的过滤函数都是按照ES提供的函数来进行抽象。
聚合
聚合函数:count(*)、count(sip)、count(UNIQUE url)、count(inbyte + outbyte)
sum()、min()、max()、avg()
stdve()、squares()、variance()
聚合函数是根据ES提供的聚合功能来进行抽象。
我们在对网络数据进行报警的时候,需要对流量进行报警。流量有内部局域网访问的流量,也有访问外部的局域网。
ES里有一个桶聚合的功能叫做filters,在filters里面可以把ip_range当成一个filters来做。
RDL脚本
通过SQL查询ES之后,还要做进一步的处理。因为虽然ES的聚合能力很强,但它聚合后的结果处理能力还是比较弱的。
我们在报警模块中开发了一套脚本语言,这个脚本语言和大部分脚本语言长得非常接近,它的主要功能就是负责查询ES并做一些简单的运算处理,再把报警输出。当然也少不了一些逻辑判断。这个脚本兼顾了一些对ES的配置功能以及运算功能,它还提供了通过SQL语句进行查询的功能,查询完之后可以进行输出。
当时有人质疑为什么不用python。首先python的并发实现起来不太人性化,如果是线程并发可能会是一个伪线程,没有完全并发出来;如果用进程的话,写了很多报警规则,在调度的时候python可能就会挂了。于是我们开发了这一套脚本,在并发上达到几十万是没有问题的,这个脚本还可以根据它的语法自己定义功能。提供这个功能可以提高规则复用的程度。
规则
在报警的时候SQLAlert有两种工作方式,第一种是当作程序来跑,写完规则后在配置文件中加入,它自己就会慢慢进行调度,基本上300秒调度一次。另一个工作方式就是它作为代理,由用户来写代码,向SQLAlert发出请求,由它对ES进行查询,得到查询结果再返回给请求者。
实例一
固定阀值报警的时间范围是过去五分钟,报警条件是字节数超过200M或者总包数超过10000个。
如图所示,前两行是定义ES的主机地址和报警输出的索引信息。中间两行是定义阀值200M和10000个数据包。SQL语句用来计算总字节数和总包数。在查询后的返回语句是过去五分钟所有的SIP和DIP聚合之后的数据。在聚合的基础上还有一个过滤功能,就是总字节数和总包数大于定义的阀值,才会把结果输出来再写回到ES里面。
实例二
我们也不知道网络中的数据量到底有多大,只知道过去有相同的访问数据。这个示例的时间范围还是对过去五分钟的数据进行报警,参考时间是昨天的当前时间段之前的五分钟。报警条件是总字节数超过200M或者总包数超过10000个,且超过历史数据的50%。
实例三
这个示例是对一段数据的变化率进行报警。参考时间是过去四周内相同时刻的30分钟时间段,参考数据是历史数据的90%的百分位数。当变化率超过参考数据的2倍时会进行报警。
在一个公司内部网络流量波动非常大的情况下,可以把当前的变化率和昨天的变化率进行对比,如果超过了昨天的变化率可能就是一个报警。
总结
我们做的SQLAlert模块主要是对报警和报警风暴的抑制,报警风暴主要是通过ES本身来进行抑制。我们对报警输出做了两次输出,第一次输出的是接受者的ES,通过SQLAlert查询ES的告警索引,再进行第二次输出,这样输出的数量就大大减少了。
我今天的分享就到这里,谢谢大家!