在SLS中快速實現異常巡檢

1、相關算法研究

1.1 常見的開源算法

  • Yahoo:EGADS
  • FaceBook:Prophet
  • Baidu:Opprentice
  • Twitter:Anomaly Detection
  • Redhat:hawkular
  • Ali+Tsinghua:Donut
  • Tencent:Metis
  • Numenta:HTM
  • CMU:SPIRIT
  • Microsoft:YADING
  • Linkedin:SAX改進版本
  • Netflix:Argos
  • NEC:CloudSeer
  • NEC+Ant:LogLens
  • MoogSoft:一家創業公司,作的內容蠻好的,供你們參考

1.2 基於統計方法的異常檢測

基於統計方法對時序數據進行不一樣指標(均值、方差、散度、峯度等)結果的判別,經過必定的人工經驗設定閾值進行告警。同時能夠引入時序歷史數據利用環比、同比等策略,經過必定的人工經驗設定閾值進行告警。
經過創建不一樣的統計指標:窗口均值變化、窗口方差變化等能夠較好的解決下圖中(1,2,5)所對應的異常點檢測;經過局部極值能夠檢測出圖(4)對應的尖點信息;經過時序預測模型能夠較好的找到圖(3,6)對應的變化趨勢,檢測出不符合規律的異常點。算法

如何判別異常?網絡

  • N-sigma
  • Boxplot(箱線圖)
  • Grubbs’Test
  • Extreme Studentized Deviate Test

PS:架構

  1. N-sigma:在正態分佈中,99.73%的數據分佈在距平均值三個標準差之內。若是咱們的數據服從必定分佈,就能夠從分佈曲線推斷出現當前值的機率。
  2. Grubbs假設檢驗:常被用來檢驗正態分佈數據集中的單個異常值
  3. ESD假設檢驗:將Grubbs'
  4. Test擴展到k個異常值檢測

1.3 基於無監督的方法作異常檢測

什麼是無監督方法:是否有監督(supervised),主要看待建模的數據是否有標籤(label)。若輸入數據有標籤,則爲有監督學習;沒標籤則爲無監督學習。
爲什麼須要引入無監督方法:在監控創建的初期,用戶的反饋是很是稀少且珍貴的,在沒有用戶反饋的狀況下,爲了快速創建可靠的監控策略,所以引入無監督方法。
針對單維度指標機器學習

  • 採用一些迴歸方法(Holt-Winters、ARMA),經過原始的觀測序列學習出預測序列,經過二者之間的殘差進行分析獲得相關的異常。
  • 針對單維度指標學習

    • 多維度的含義(time,cpu,iops,flow)
    • iForest(IsolationForest)是基於集成的異常檢測方法spa

      • 適用連續數據,具備線性時間複雜度和高精度
      • 異常定義:容易被孤立的離羣點,分佈稀疏且離密度高的羣體較遠的點。
    • 幾點說明設計

      • 判別樹越多越穩定,且每棵樹都是互相獨立的,能夠部署在大規模分佈系統中
      • 該算法不太適合特別高維度數據,噪音維度維度和敏感維度沒法主動剔除
      • 原始iForest算法僅對全局異常值敏感,對局部相對稀疏的點敏感度較低

1.4 基於深度學習的異常檢測

論文題目:《Unsupervised Anomaly Detection via Variational Auto-Encoder for Seasonal KPIs in Web Applications》(WWW 2018)3d

  • 解決的問題:針對具備週期性的時序監控數據,數據中包含一些缺失點和異常點
  • 模型訓練結構以下

​​​​​​​

  • 檢測時使用了MCMC填補的技術處理觀測窗口中的已知缺失點,核心思想根據已經訓練好的模型,迭代逼近邊際分佈(下圖表示MCMC填補的一次迭代示意圖)

​​​​​​​

1.5 使用有監督的方法作異常檢測

  • 標註異常這件事兒,自己很複雜?rest

    • 用戶定義的異常每每是從系統或者服務角度出發,對數據進行打標,所關聯的底層指標、鏈路指標繁雜,沒法從幾個維度出發(更多的是系統的一個Shapshot)
    • 在進行架構層設計時,都會進行服務自愈設計,底層的異常並未影響到上層業務
    • 異常的溯源很複雜,不少狀況下,單一監控數據僅是異常結果的反應,而不是異常自己
    • 打標樣本數量不多,且異常類型多樣,針對小樣本的學習問題還有待提升
  • 經常使用的有監督的機器學習方法日誌

    • xgboost、gbdt、lightgbm等
    • 一些dnn的分類網絡等

2、SLS中提供的算法能力

  • 時序分析

    • 預測:根據歷史數據擬合基線
    • 異常檢測、變點檢測、折點檢測:找到異常點
    • 多週期檢測:發現數據訪問中的週期規律
    • 時序聚類:找到形態不同的時序

​​​​​​​

  • 模式分析

    • 頻繁模式挖掘
    • 差別模式挖掘

​​​​​​​

  • 海量文本智能聚類

    • 支持任意格式日誌:Log4J、Json、單行(syslog)
    • 日誌經任意條件過濾後再Reduce;對Reduce後Pattern,根據signature反查原始數據
    • 不一樣時間段Pattern比較
    • 動態調整Reduce精度
    • 億級數據,秒級出結果

​​​​​​​

3、針對流量場景的實戰分析

3.1 多維度的監控指標的可視化


具體的SQL邏輯以下:

* | 
select
   time,
   buffer_cnt,
   log_cnt,
   buffer_rate,
   failed_cnt,
   first_play_cnt,
   fail_rate 
from
   (
      select
         date_trunc('minute', time) as time,
         sum(buffer_cnt) as buffer_cnt,
         sum(log_cnt) as log_cnt,
         case
            when
               is_nan(sum(buffer_cnt)*1.0 / sum(log_cnt)) 
            then
               0.0 
            else
               sum(buffer_cnt)*1.0 / sum(log_cnt) 
         end as buffer_rate, 
sum(failed_cnt) as failed_cnt, 
sum(first_play_cnt) as first_play_cnt , 
         case
            when
               is_nan(sum(failed_cnt)*1.0 / sum(first_play_cnt)) 
            then
               0.0 
            else
               sum(failed_cnt)*1.0 / sum(first_play_cnt) 
         end as fail_rate 
      from
         log 
      group by
         time 
      order by
         time
   )
   limit 100000

3.2 各指標的時序環比圖


具體的SQL邏輯以下:

* |
select 
    time,
    log_cnt_cmp[1] as log_cnt_now,
    log_cnt_cmp[2] as log_cnt_old,
    case when is_nan(buffer_rate_cmp[1]) then 0.0 else buffer_rate_cmp[1] end as buf_rate_now,
    case when is_nan(buffer_rate_cmp[2]) then 0.0 else buffer_rate_cmp[2] end as buf_rate_old,
    case when is_nan(fail_rate_cmp[1]) then 0.0 else fail_rate_cmp[1] end as fail_rate_now,
    case when is_nan(fail_rate_cmp[2]) then 0.0 else fail_rate_cmp[2] end as fail_rate_old
from
(
select 
    time, 
    ts_compare(log_cnt, 86400) as log_cnt_cmp,
    ts_compare(buffer_rate, 86400) as buffer_rate_cmp,
    ts_compare(fail_rate, 86400) as fail_rate_cmp
from (
select 
      date_trunc('minute', time - time % 120) as time, 
    sum(buffer_cnt) as buffer_cnt, 
    sum(log_cnt) as log_cnt, 
    sum(buffer_cnt)*1.0 / sum(log_cnt) as buffer_rate, 
    sum(failed_cnt) as failed_cnt,  
    sum(first_play_cnt) as first_play_cnt ,
    sum(failed_cnt)*1.0 / sum(first_play_cnt) as fail_rate
from log group by time order by time) group by time)
where time is not null limit 1000000

3.3 各指標動態可視化


具體的SQL邏輯以下:

* | 
select 
    time, 
    case when is_nan(buffer_rate) then 0.0 else buffer_rate end as show_index,
    isp as index
from
(select 
    date_trunc('minute', time) as time, 
    sum(buffer_cnt)*1.0 / sum(log_cnt) as buffer_rate,
    sum(failed_cnt)*1.0 / sum(first_play_cnt) as fail_rate,
    sum(log_cnt) as log_cnt,
    sum(failed_cnt) as failed_cnt,
    sum(first_play_cnt) as first_play_cnt,
    isp
from log group by time, isp order by time) limit 200000

3.4 異常集合的監控Dashboard頁面

  • 異常監控項目的背後圖表SQL邏輯
* | 
select 
    res.name 
from ( 
    select 
        ts_anomaly_filter(province, res[1], res[2], res[3], res[6], 100, 0) as res 
    from ( 
        select 
            t1.province as province, 
            array_transpose( ts_predicate_arma(t1.time, t1.show_index, 5, 1, 1) ) as res 
        from ( 
            select
                province,
                time,
                case when is_nan(buffer_rate) then 0.0 else buffer_rate end as show_index
            from (
                select 
                    province, 
                    time, 
                    sum(buffer_cnt)*1.0 / sum(log_cnt) as buffer_rate, 
                    sum(failed_cnt)*1.0 / sum(first_play_cnt) as fail_rate, 
                    sum(log_cnt) as log_cnt, 
                    sum(failed_cnt) as failed_cnt, 
                    sum(first_play_cnt) as first_play_cnt
                from log 
                group by province, time) ) t1 
            inner join ( 
                select 
                    DISTINCT province 
                from  ( 
                    select 
                        province, time, sum(log_cnt) as total 
                    from log 
                    group by province, time ) 
                where total > 200 ) t2 on t1.province = t2.province  
        group by t1.province ) ) limit 100000
  • 針對上述SQL邏輯的具體分析

​​​​​​​​​​​​​​


原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索