騰訊運維的 AI 實踐
我是一個做機器學習的人,目前接觸運維的時間並不長,大約半年左右。 主要做社交網路的運維、監控和異常檢測方面的工作。本文將按照下面四大塊內容分享。
1. 時間序列異常檢測
監控領域做運維,最基礎的是時間序列的異常檢測。如果是基於機器學習的智慧運維,主要分三個場景:
-
第一步是發現問題,如果我們無法發現問題就無法定位問題、甚至解決問題。
既然提到發現問題,最主要的是發現一些時間序列的異常、日誌的異常和裝置的異常以及網路流量的異常。
-
第二步,發現問題之後自然要分析問題,發現問題並不足以解決問題。
分析完後,當然想自動或者半自動的智慧化把問題解決掉,這就是我們最後要做的工作。
-
第三步,解決問題,包括擴容、排程甚至優化方面的工作。
怎樣才能發現問題?首先要知道我們的問題究竟在哪兒,要知道時間序列到底代表什麼。時間序列包括線上的使用者量、主機CPU使用量和定時任務等。
上圖有六個異常情況的例子,左上角的圖是使用者陡升了,可能做了一些活動。後面的圖又下跌了,可能是異常變更導致的使用者量下降。
做運維的都知道,時間序列異常檢測是一個老大難的問題,因為以前的技術是使用一些人工巡檢或者配閾值的方式監控時間序列。
首先,這樣做有一定的風險在,包括制定閾值,可能告警電話比較多。
其次,海量的時間序列不是一條、兩條甚至十條,可能是成千上萬的而且種類還特別多。
還有,單獨建立獨立的模型是不現實的,配閾值也是不現實的,不管是配最大值、最小值或者方差是不能解決這個場景問題的。產品在未來可能發生變化或者使用者量發生變化了,閾值可能並不能解決。
針對上述難點和挑戰,提出一個問題來,如何找到通用的演算法同時監控百萬條曲線?
如何通過更加普適性的演算法來進行時間序列異常的檢測呢?首先看傳統的方法,說到傳統方法自然想到統計學的做法,通常用ARMA模型,要做這個公式模型就需要定階,擬合這個模型後就可以做這一塊工作了。
使用統計學的演算法,會有一個前提假設條件,需要假設時間序列有自相適性,假設它是平穩或者弱平穩的狀態。
對於運維的場景,比如說 DAU 或者線上使用者量有一個週期性的特性,在某些場景下用這個演算法是 OK 的。
但是,在很多場景下,是沒有辦法判斷這個時間序列是否具有周期性,這時候就需要人工判斷或者其他方法來做。
在這些假設條件下,上面的演算法是有一定侷限性的,並不能完全適用於所有的時間序列場景。
提到時間序列,有一些其他的想法。比如說時間序列是一維的時間序列。
在一維情況下未必能看得很清楚,如果提升到高維空間上,用高維空間的手段來看原始的時間序列是否存在某些問題。
這確實具有一定的優勢,但是這樣的方法也是聚在某一些具體場景下,同樣存在一定的弊端,並不能適用於所有的時間序列場景。
跟很多搞 AI 的同學交流過,提到時間序列,他們第一反應就是文字或者語音的場景。文字和語音就是我跟你說一段話,你能生成文字或者語音,或者我說對聯的上聯,可以對出下聯。
這比較適合語音或者文字的場景,因為有固定的模式在。
比如說“我吃蘋果”,“我吃”後面肯定接某個物品。
時間序列在這個點陡升是正常的,或者有一些時間序列在這個點陡升是異常的,基於單條時間序列或者同類型的時間序列來做,RNN 或者 LSTM 是有一定效果的,這在我們的場景上也有一些嘗試。
既然傳統的時間序列有各種各樣的問題,我們就要想辦法解決這些問題。
傳統的統計演算法是基於正態分佈的假設,基於弱平穩型的假設和基於趨勢性、週期性的假設。
我們能不能把這些問題去掉呢?比如說時間序列裡面提到了異常假設,你提到的異常,對應的就是正常,異常和正常就對應了二分類的問題,標籤等於零或者等於一。
在這種使用場景下就要轉化為機器學習的問題,有一些是異常,有一些是正常。
其他的機器學習就是二分類的問題,這在我們這種情況下也有一定的弊端,就在於在業務平穩情況下大部分業務指標是正常的,即使是在系統裡,點選率也不會太高,一般出現 100 個,別人點 4 個就差不多了,而且大部分面臨著樣本不均衡、不全面、稀少的問題。
如何解決這些問題?如果從人工巡檢或者人工標註的方法,是沒有精力和時間來標註這些異常樣本,大部分時間花在找正常樣本。我們就使用了無監督和有監督有機結合的方案。
為什麼要使用無監督演算法呢?尋找異常樣本的時候,就相當於在海量時間序列裡面撈一根針,這個成本很高。有沒有一些方法,比如說通過篩子的方法,把從大海里面撈一根針變成從游泳池裡面撈一根針呢?用無監督或者統計判別的方法,可以把範圍大大的縮小。
使用這些技巧縮小,把演算法過濾到大量的正態樣本,剩下的就是疑似異常。人工標註的人力成本會在這個地方得到體現,人工標註樣本後,再通過有監督學習演算法對這些樣本進行訓練,從而提升系統的準確率和召回率。
我這邊是用了一個不太成熟的解決方法,就是無監督和有監督的技巧。
這張圖是織雲 Monitor 時間序列異常檢測的技術框架。離線訓練資料模組是資料儲存,包括樣本的標註、提取,把模型訓練好之後,並沒有做完這個事情,這只是離線評測或者評估。
剩下的要做線上的預測,要把離線訓練模型載入到線上,在時間序列上需要讀取這份資料。我們的演算法沒有辦法一次性把這個調到最好,就需要不斷迭代的過程。
既然需要迭代,就要切流量分成兩塊,同時跑兩個演算法,哪個演算法高效就把哪個演算法推到主流量上,通過 ABTest 模組進行技術更新和迭代。整個技術框架大概就是這樣的,細節將在下面會詳細闡述一下。
第一層演算法是統計判別和無監督的演算法,都是在無監督演算法的範疇裡面。
左上角的時間序列化,用 3-sigma 原理,就是用 S 減均值,方差大於 3 倍,用這個可以優化出來,同樣可以由這個無監督的框架。3-sigma 有可以解決的和不可以解決的點,存在一定的弊端。
比如左下角的圖用 3-sigma 是沒有辦法監督出來,因為沒有超過昨天或者歷史的最大值,我們就需要其他技巧來解決這個問題。
談到其他技巧,需要講一下無監督的演算法。無監督的演算法是沒有標註的過程,我們用“孤立森林”或者是 SVM、RNN 來解決問題。用孤立森林,它的目的是從多維資料空間中尋找異常點。
SVM 是建立超平面來尋找異常點。無監督演算法也有一定的弊端,比如說左上角這幅圖,可以明顯找到藍色的地方是異常,左下角的圖就是異常任務。
無監督演算法也有能解決的問題和不能解決的問題。其實我們很難保證每一次無監督輸出的異常都是真的異常。左上角的圖就標註為異常。左下角的圖,由於每天或者每週都是這樣,我們就標註為正常,後面會進行人工標註。
孤立森林是一個無監督學習的演算法,由南京大學教授提出的。這裡適用於連續數量的異常檢測,病人使用多棵樹形成森林來判斷是否異常。
比如右上角這幅圖,中間的點認為是正常點,外圍的是異常點。
我們用孤立森林可以很輕鬆的分離開,認為這些是異常點。而後端就很難分開,我們認為後端是很難被發現的異常。
這就是無監督學習演算法,這一塊也有一些應用場景和使用的地方。
無監督學習演算法,遠遠不只是孤立森林,還有一些周邊的演算法,如 SVM。
SVM 是作為線性的方法,但是使用了超平面的思想。就是把一個點進行提升或者平面加固,用超平面的思想把點和點之間區分開。
舉個例子,比如說桌面上有很多蘋果、梨、乒乓球和西瓜,用相同的力度各自拍一下,由於蘋果、梨、乒乓球和西瓜的重量不一樣,彈出來的高度也不一樣,可以利用彈出來的高度使用一個平面區分開,SVM 就是用了這樣一個思想。
右邊這副圖裡,這個圓或者這些紅點,很難找到一個平面把它區分開。平面中只能找到圓形的框架,高維空間或者特徵空間裡面可以容易的找到一個高維平面區分開,這是一個無監督的思想,通過它以把找出異常點。
RNN 是複製的神經網路。右邊這副圖是左邊輸入,右邊是輸出。訓練這個神經網路,左邊的輸入和右邊的輸出是一樣,中間的節點遠小於左邊和右邊的節點個數。比如說左邊的輸出等於右邊的輸出,中間做了一個資訊壓縮的過程,提煉了關鍵的特徵。
對於一些正常點和大部分點,輸入和輸出的誤差不會變得特別大,但是對於一些異常點來說,它的特徵跟正常點有明顯區別。
使用這個訓練好的神經網路,輸入和輸出的誤差會相對偏大一點。在相對偏大的過程中,認為誤差偏大的這些點就是我們要尋找的異常點。
在這個過程中要做特徵工程的工作,判斷一些疑似異常。
無監督演算法也並不能解決所有問題。比如中下圖,用無監督演算法,藍色的點都會認為異常點,因為用擬合都認為它肯定是高異常。基於週期性或者影象來看可能是無異常的。
我們把人工標註過的異常或者疑似異常樣本進行訓練,通過決策樹或者 RF、GBDT 的模型,得到我們想要的值,然後再通過這個樣本就可以得到訓練和預測的過程。
時間序列是可以做特徵的。時間序列的特徵可以大概分為三類:
-
時間序列的統計特徵
-
時間序列的擬合特徵
-
時間序列的分類特徵,如形狀或走勢的分類。
時間序列的統計特徵。右邊這幅圖是一個時間序列,大家就算沒有做過機器學習也知道最大值、最小值等等指標,也可以寫出來,這些公式我們之前都有接觸過。
講一下時間序列的擬合特徵,這裡面使用了子的時間序列模型,去提煉一些特徵,可以使用帶權重的移動平均演算法或者 EWMA 等等演算法。
左邊的圖是時間序列,紅色的點是想要提取的時間序列特徵的片段。
我們現在進行平均的過程,通過原始的時間序列,可以得到光滑後的時間序列,自然就有一個光滑值,光滑值可以作為我們的一個特徵。
用 EWMA 或者 Double EWMA 演算法,把時間序列進行平滑操作,平滑後的值可以作為特徵的工具。
對於這些值,基於海量時間序列很難通過一種模型,如 EWMA。但是,可以把時間序列輸出的模型作為一個特徵,通過這個特徵作為一個整合學習的思想,用孤立森林的模型對這些特徵進行學習,相當於把很多個時間序列的模型融合到最終的一個大的模型裡面,這樣就能解決很大一部分問題。
如此的話,這個模型具有更好的通用性,不僅可以檢測一些DAU或者再現使用者量,同樣也可以檢測一些主機資訊或者定時任務的一些指標。這就是時間序列提取特徵的過程,使用了整合學習的思想。
除了時間序列提取擬合特徵,還可以得到分類特徵。右邊這些圖是很多時間序列,上面這些圖是昨天放量型的,開始有走勢,今天顯示比較平穩。
第二部分是毛刺型的。
第三部分是平穩走勢型的。我們可以提取其他值的特徵,把序列簡單的大概分成幾類。通過這一塊,我們不僅做了聚類,也做了分類。這個時間序列,通過走勢就可以簡單的進行分類的操作。
AIOps 智慧監控,除了準確率、機器學習框架還有召回率。織雲只能監控的準確率達 90%。通過計算召回率也得到了相應比較高的值達 70%。
除了前面所提到的基於歷史資料的聚類和關聯分析、相似判斷分析與提取,我們現在做的是時間序列的異常檢測和聯動分析框架,包括時間序列的未來趨勢預測。
我們現在基於歷史資料,學習歷史資料,預測未來資料,這是時間序列相關技術的整體規劃。
2. 智慧多維下鑽分析
既然發現完問題,自然要有分析問題的過程。這幅圖就是一個時間序列,展示成功量或者播放成功率,通過業務埋點或者監控系統,可以匯聚到相關資料,統計的維度有 IOS、安卓,客戶端版本,成功量、失敗量。
通過人工巡檢或者人工配置閾值的方式判斷成功率是否下跌,由於業務變化,確實不一樣,以前異常不代表未來也異常。
第二步是人工查詢可疑維度,檢視成功率和成功數,看可疑的維度。
人的精力畢竟有限,每次故障都人力分析,沒有這麼多人力,而且基本上先分析單個維度,再分析多個維度,隨著維度的增加,有一個組合是二元次方,根本就不在認得搜尋能力範圍。
因此我們必須引入機器學習或者其他的思想來解決這些的問題。
基於機器學習的根因分析分兩層:
-
第一步,發現問題。資料儲存或者時間序列的異常等等;
-
第二步,分析問題。我們自然要拉取正負樣本,以一個工程來分析根因。
左邊的發現問題相當於單點應用,是異常檢測的模型。右邊的分析問題是另外一個學界,是分析或者定位故障的過程。
這兩個過程串聯起來就是白皮書裡面寫的串聯應用,我們也在做這一塊工作,把兩個模組打通到第一層上,是一個發現問題、定位問題、分析問題的過程。
提到根因分析的機器學習模型,我們也有其他想法,可以把剛才說的JSD或者其他框架提煉出來。
我們通過一些調研,既然提到根因分析,就要輸出一個異常的定位或者解釋。
首先這個模型必須要有解釋性,不可能用一個深度學習或者深度神經網路,這個雖好,但是沒有解釋性。
它要求的結果是輸出一個規則或者輸出一個解釋。比如說裴教授論文裡面寫了,用“決策樹”的技巧,可以用減支的方案來做。這個模型的性質是解釋性好,可以進行離線分析。
基於機器學習的決策樹的模型的大概想法和框架大概如上圖所示。成功率下跌了可以作為異常樣本,成功率保持穩定的是正常樣本。
通過一定的比例或者特徵工程可以得到很多特徵,以這些特徵可以進一步得到有監督的模型學習,最後輸出一個規則體或者疑似異常的過程。
基於機器學習的模型,首先我們要選擇一些樣本,並且得到相應的特徵,使用這樣一棵決策樹。建樹時間比較長,也需要一定的訓練時間,隨著業務的遷移,當前的這棵決策樹現在訓練好了,半個月後可能就不太適用了,因此我們進行了其他方案的調研。
找到一些關鍵節點,然後通過關鍵節點回溯到根節點,自然就會打出根因,我們進行冗餘規則的合併,最後可以輸出最終的異常。
最終的異常的解釋就是我們剛剛所說的發現問題,也就是發現異常,這就是最大可容的問題。決策樹的建樹規模會很大,特徵工程也會很複雜,對於這一塊我們也嘗試了其他的方案。
根因分析的一般流程是資料處理、剪枝操作、維度組合。
我們要做的是移除正常維度,聚焦異常維度。對決策樹等模型選擇合適的場景,就需要對決策樹的理念和理論要有更加細緻的瞭解。
決策樹正如我們剛剛所說的,最終會用到熵和 Gini 係數來做。
左邊這副圖男女分佈情況,如果對這款 APP 來說,男性下載量大,女性下載量小,是不是可以得出結論這款APP男性受歡迎度大,女性受歡迎度小。
比如說音樂,男女喜好比例並不是 1:1,如果男女分佈本來不均衡,你從得到的下載量判斷出這個APP是否受男女歡迎。
中間這幅圖是 APP1 的下載量,從 APP1 的下載量和男女分佈情況來看,幾乎保持一致,但是 APP2 的下載量差異比較大。
我們本質上是希望做一個概率之間的距離,其實點和點之間是可以描述距離的,同樣概率和概率分佈之間也有距離。
概率之間的距離可以用 KL 散度來做,KL 散度具有不對稱性。
概率分佈之間的距離可以用 Jensen Shannon Entropy 對稱模型來做。
比如說左邊的圖和中間的圖,它們兩個概率分佈幾乎為零,可得出 APP1 的下載量是男女同等受歡迎的。
左邊這幅圖和右邊這幅圖APP下載量和男女分佈情況差異很大,可得出 APP2 可能更受某一類人群的歡迎。
提到根因分析的機器學習模型,我們也有其他想法,可以把剛才說的 JSE 或者其他框架提煉出來。
要計算概率分佈,首先要考慮量的問題,比如說某個人群基數很少或者在某個時間點人群數量很少,在這種情況下,總量或者其他波動很大,有可能一個使用者沒有登入上成功率就直接為零了。
只使用概率分佈不能解決所有問題,除了總量或者成功量,還要考慮一些總量或者貢獻值的指標。因此我們使用了微軟提出的 JSD 的方案,不僅要考慮概率分佈,還要考慮量。
比如說失敗率陡升或者成功率下跌了,幾個量交叉在一塊,如果都發生異常,我們才認為是異常。如果只是概率分佈距離發生了異常,做的量小,這個差距還是很大的。
3. 告警收斂根源分析
時間序列異常檢測是發現問題,發現問題串聯起來就是分析問題。其實報警根源分析也是相當於串聯應用的場景。
在海量的時間序列告警情況下,哪一些屬於異常?
有一些可能是網路抖動,有一些是機房故障,有一些是程式異常或者有一些日誌變更,導致了我們時間序列異常,這時候可以通過報警根源來分析哪些發生異常。
這是一個串聯應用場景,它的挑戰難度比時間序列還要大。時間序列首先要告警相對準,不可能前面時間序列告警準確率只有 20%,後面希望做到 100%,這是不可能的。
首先,我們要解決歷史包袱,如誤告郵件多、誤告訊息多或者告警電話多等等。
比如說搞活動,海量的時間序列可能也會發現走勢跟之前不一樣,我們能否通過根本的原因來發現它是搞活動還是程式釋出導致的異常,這是我們當前在想的問題。
織雲 ROOT 根源分析,我們通過抓包來得到呼叫關係,通過機器學習的思想來發現哪些地方是我們最想要的根因。
通過拓撲調研分析來得到關鍵節點,這些關鍵節點就是我們重點要分析的東西。關鍵節點間的呼叫拓撲關係可以通過社交網路技術來實現。
告警收斂我們正在做,不管某個程式是否釋出了,在這段時間有兩條時間序列經常一起發現異常,其實就有某種關聯關係。
哪些告警是經常一起告警出來的,通過提煉告警規則得到一個關係,然後排查告警的時間差。
比如說 A 發生告警,隨後 B 發生告警的概率可以輕易的算出來,只要能積累相應的資料和報警資料準。告警收斂可以等待佇列,最後把告警傳送出來。通過這個可以做到告警壓縮和收斂。
通過一些檢測的方式得到一個 0 和的 1 序列,其中 0 是異常,1 是正常。經過 KPI技術判斷這兩條告警序列是否一致,告警的時候一塊告警,不告警的時候一塊不告警。通過 KPI 的統計方法,來判斷這兩條告警序列的相似性。
如果相似性高,我們認為這兩條序列是相關的。如果告警的相關性很低,我們認為是不相關的。基於告警的劃分,我們也可以做到告警收斂和壓縮。
這是織雲 ROOT 的根源分析的過程圖。比如收取到一個模組 ID,把告警序列拉取出來,通過調研關係進行根源分析。這裡面有一個是主調告警,有一個是被調告警,這就是根源和異常的過程。
4. AIOPS的未來規劃
織雲 AIOps 的規劃大概是三類:
-
首先是發現問題,比如時間序列的異常問題檢測,包括聚類、分類、區域性相似度、整體相似度和關鍵部分提取。
-
根因分析,除了多維下鑽分析,我們還會做故障傳播鏈分析,這個正在進行中。
-
最終是要解決問題。解決問題就是智慧決策,包括擴容、決策、優化、排程的框架。
說明:本文根據 騰訊 張戎博士於 GOPS · 深圳站的分享整理而成。
智慧運維時代已全面來臨,AIOps 風向標!GOPS 2018 · 上海站:第十屆全球運維大會, 騰訊運維雙雄 專場將會繼續帶來智慧運維的深度分享。敬請期待。
專場門票的10位獲獎名單揭曉 :arrow_down:
ofollow,noindex"> 戳這裡
(名單見於文章末小編留言回覆)