Elasticsearch開發實戰篇——基於ES的SQL報警引擎

IT大咖說發表於2019-03-03

Elasticsearch開發實戰篇——基於ES的SQL報警引擎


內容來源:2017年6月10日,南京雲利來軟體科技有限公司張立丹在“Elastic Meetup 南京”進行《基於ES的SQL報警引擎》演講分享。IT 大咖說作為獨家視訊合作方,經主辦方和講者審閱授權釋出。

閱讀字數:1499 | 4分鐘閱讀

嘉賓演講視訊回顧及PPT:suo.im/Z5iA5

摘要

一般來說,ES的查詢語言在使用過程中會比較麻煩,來自南京雲利來軟體科技有限公司的張丹立老師從四個方面來分析把ES換成SQL後的狀態。

概述

ES的聚合能力非常強,延遲低;而SQL相對於DSL來說有較高的抽象層次,更為大眾所熟悉。在做報警引擎的時候我們發現,純用ES難以解決我們的問題,必須要在ES計算後進行第二次處理。RDL用“規則描述語言”,提供計算機輔助功能。

SQL及擴充套件

Elasticsearch開發實戰篇——基於ES的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提供的聚合功能來進行抽象。

Elasticsearch開發實戰篇——基於ES的SQL報警引擎

我們在對網路資料進行報警的時候,需要對流量進行報警。流量有內部區域網訪問的流量,也有訪問外部的區域網。

ES裡有一個桶聚合的功能叫做filters,在filters裡面可以把ip_range當成一個filters來做。

RDL指令碼

通過SQL查詢ES之後,還要做進一步的處理。因為雖然ES的聚合能力很強,但它聚合後的結果處理能力還是比較弱的。

Elasticsearch開發實戰篇——基於ES的SQL報警引擎

我們在報警模組中開發了一套指令碼語言,這個指令碼語言和大部分指令碼語言長得非常接近,它的主要功能就是負責查詢ES並做一些簡單的運算處理,再把報警輸出。當然也少不了一些邏輯判斷。這個指令碼兼顧了一些對ES的配置功能以及運算功能,它還提供了通過SQL語句進行查詢的功能,查詢完之後可以進行輸出。

Elasticsearch開發實戰篇——基於ES的SQL報警引擎

Elasticsearch開發實戰篇——基於ES的SQL報警引擎

當時有人質疑為什麼不用python。首先python的併發實現起來不太人性化,如果是執行緒併發可能會是一個偽執行緒,沒有完全併發出來;如果用程式的話,寫了很多報警規則,在排程的時候python可能就會掛了。於是我們開發了這一套指令碼,在併發上達到幾十萬是沒有問題的,這個指令碼還可以根據它的語法自己定義功能。提供這個功能可以提高規則複用的程度。

規則

Elasticsearch開發實戰篇——基於ES的SQL報警引擎

在報警的時候SQLAlert有兩種工作方式,第一種是當作程式來跑,寫完規則後在配置檔案中加入,它自己就會慢慢進行排程,基本上300秒排程一次。另一個工作方式就是它作為代理,由使用者來寫程式碼,向SQLAlert發出請求,由它對ES進行查詢,得到查詢結果再返回給請求者。

例項一

固定閥值報警的時間範圍是過去五分鐘,報警條件是位元組數超過200M或者總包數超過10000個。

Elasticsearch開發實戰篇——基於ES的SQL報警引擎

如圖所示,前兩行是定義ES的主機地址和報警輸出的索引資訊。中間兩行是定義閥值200M和10000個資料包。SQL語句用來計算總位元組數和總包數。在查詢後的返回語句是過去五分鐘所有的SIP和DIP聚合之後的資料。在聚合的基礎上還有一個過濾功能,就是總位元組數和總包數大於定義的閥值,才會把結果輸出來再寫回到ES裡面。

例項二

我們也不知道網路中的資料量到底有多大,只知道過去有相同的訪問資料。這個示例的時間範圍還是對過去五分鐘的資料進行報警,參考時間是昨天的當前時間段之前的五分鐘。報警條件是總位元組數超過200M或者總包數超過10000個,且超過歷史資料的50%。

Elasticsearch開發實戰篇——基於ES的SQL報警引擎

例項三

這個示例是對一段資料的變化率進行報警。參考時間是過去四周內相同時刻的30分鐘時間段,參考資料是歷史資料的90%的百分位數。當變化率超過參考資料的2倍時會進行報警。

在一個公司內部網路流量波動非常大的情況下,可以把當前的變化率和昨天的變化率進行對比,如果超過了昨天的變化率可能就是一個報警。

Elasticsearch開發實戰篇——基於ES的SQL報警引擎

總結

我們做的SQLAlert模組主要是對報警和報警風暴的抑制,報警風暴主要是通過ES本身來進行抑制。我們對報警輸出做了兩次輸出,第一次輸出的是接受者的ES,通過SQLAlert查詢ES的告警索引,再進行第二次輸出,這樣輸出的數量就大大減少了。

我今天的分享就到這裡,謝謝大家!


相關文章