項目背景
公司內部封裝了NLP通用算法的GRPC服務,好比文本情感識別、文本分類、實體識別等, 提供給大數據等其餘部門實時調用。算法
RPC 服務的調用日誌,經過Filebeat、Logstash 實時發送到Elasticsearch,如今須要經過對日誌的調用狀況實時統計分析,判斷調用狀況是否出現異常,並對異常狀況可以實時告警。bash
業務場景分析
使用ES 的watcher 插件建立一個threshold alert, 設置預警規則,當一個時間週期內的數據量達到閾值, 就進行告警。機器學習
這種方案優勢是,設置起來比較簡單,只要設置query的條件,以及閾值就能夠快速完成。 缺點是,這種方案比較適合粗粒度,而且閾值明確的狀況下設置。性能
設想一下,若是要作到分鐘級實時監控,而且對異常點進行告警通知,若是用規則來設置,很難知足這種場景。 針對這種場景,很容易想到,使用Machine Learning (ML)的方法,根據以往的數據變化趨勢,來主動發現異常點,那就簡單多了。學習
針對這種需求, 有不少解決方案,好比,把日誌實時發送到KAFKA,再用FlinkML 來作機器學習,訓練異常檢測模型, 不過多討論這種方案。 如題, 這裏介紹一種更簡單的方案,使用 ES Stack 提供的 ML 模塊, 很容在ES Stack上快速體驗AIOps。大數據
實踐經驗
Requirements
日誌結構
{
"@timestamp": "2019-10-09T09:10:22.547Z",
"@version": "1",
"call_day": "20191009",
"call_hour": "2019100909",
"call_minute": "201910090910",
"call_time": "10-09 09:10:21.714317",
"cost": 0.004031,
"method": "Nlp.ContentCategory",
"month": "10",
"service_name": "mg",
"timestamp": "2019-10-09T09:10:22.547Z"
}
複製代碼
目的
步驟
建立Jobui
有四種建立ML Job的模式:spa
爲了簡單起見,這裏使用單一指標模式來建立ML Job插件
配置告警閾值3d
針對檢測結果的嚴重程度進行郵件告警
查看檢測結果
經過Anomaly Explorer 能夠很容易找到異常的點
同時,經過Metric Viewer也很直觀的查看異常周邊的變化趨勢,下面舉例介紹一下,2019-09-19異常點的狀況
從上圖能夠看出,在10:00/09:00/08:00/07:00 分別檢測出了不一樣程度的異常, 其中severity值的大小,代表了異常的嚴重程度,severity值越大,說明這個異常越偏離正常狀況。
probability是事情發生的機率,值越小,這個事件發生的可能性越小,從而說明若是這個事件發生了,確定是不尋常的,跟上面severity反應的狀況也是自洽的。
typical 是典型值,就是根據以往數據學習的模型,預測這個時間段的數據量是應該是多少
actual 是實際值,是這個時間段的統計的真實數據量,若是跟typical差別越大,出現異常的可能性就越大
產生結果解釋
上述的檢測結果來自真實業務場景,在7點到10點之間的業務調用方出現異常,致使在7點到10點之間的RPC服務日誌產生量減小。ML 經過對以往數據的特徵的學習,對這個時間段的日誌量進行預測,發現實際結果與預測結果不符合。 在10點之後,業務調用方恢復正常,預測的結果跟實際調用量也是相吻合,在最終的結果圖上也是反映回到正常曲線。
Bucket Span 調優
Bucket (桶) ,在進行實時數據流分析的時候,使用桶來區分指定時間窗口的數據,桶的大小,反映了每一個窗口的數據量的大小, 也就是每次給ML喂的數據量的大小。
上面的結果是對桶大小進行調優後的效果,選擇的Bucket Span 是5min, 最初選擇的Bucket Span是15min, 沒有把異常點很好的檢測出來。
上圖桶大小是15min,從圖上能夠看出來,沒有把7點這個異常點檢測出來,同時異常的重要程度不夠。
設置1min的效果,一樣不能把異常點檢測很好的出來,並且受到噪音的干擾比較大,檢測到不少嚴重程度很低的小的異常點。
調優參考:
桶的大小不宜設置過小,若是過小,雖然餵給ML的數據變多,可是在很小的時間段內,數據的變化比較頻繁,產生大量的噪音,不利於模型的學習。反之,若是桶的大小設置太大了,將會丟掉不少細節信息,並且可能致使餵給ML的數據量不足,甚至把某個異常點給丟掉了。桶的大小要根據業務場景來,如上的場景,想盡快發現調用的異常,在數據量比較充足的狀況下,設置5min是比較合適的。固然,這也不是絕對的狀況,須要不斷地調整這個值的大小,找到合適的值。
ES ML 提供了一鍵預估(Estimate bucket span) Bucket大小,可是這個功能並非很智能,不能徹底依賴,還須要本身不斷調試
儘可能給ML喂更多充足的數據,數據量太少,ML不能很好的擬合數據,預測的結果也是不許確的
排除掉一些已知的「異常」數據,好比,週末的數據調用量降低不少,若是也直接餵給模型的話,會對預測結果產生干擾。好在,ES 提供了calendar功能,能夠把特定時間段的移除,這個時間段的數據不算作異常。
使用多指標模式,選擇更多的影響因子,使訓練出來的模型更加健壯
因爲數據不斷變化,持續把更多更新的數據餵給模型,使其可以學習到新的特徵,以適應新的數據
總結
一個完善的AIOps體系還有不少工做要作,上述只是整個體系中一小塊,好在ES Stack如今愈來愈完善,下一步能夠考慮把APM、Machine Learning整合起來,使用APM 對系統性能進行監控,使用ML對系統的各項指標進行建模,預測機器的使用趨勢,並作到動態伸縮。