摘要:本次演講将為大家介紹攜程實時智能異常檢測平台——Prophet。到目前為止,Prophet基本覆寫了攜程所有業務線,監控名額的數量達到10K+,覆寫了攜程所有訂單、支付等重要的業務名額。Prophet将時間序列的資料作為資料輸入,以監控平台作為接入對象,以智能告警實作異常的告警功能,并基于Flink實時計算引擎來實作異常的實時預警,提供一站式異常檢測解決方案。
演講嘉賓簡介:潘國慶,攜程大資料研發經理。
點選檢視本場直播>>>
更多2019 Flink Forward 大會視訊>>>以下内容根據演講視訊以及PPT整理而成。
https://developer.aliyun.com/live/1790本次分享主要圍繞以下四個方面:
- 背景介紹
- Prophet
- 智能化與實時化
- 挑戰與展望
一、背景介紹
1.規則告警帶來的問題
大部分監控平台是基于規則告警實作監控名額的預警。規則告警一般基于統計學,如某個名額同比、環比連續上升或下降到一定門檻值進行告警。規則告警需要使用者較為熟悉業務名額的形态,進而才能較為準确的配置告警門檻值,這樣帶來的問題是配置規則告警非常繁瑣、告警效果也比較差,需要大量人力物力來維護規則告警。當一個告警産生時,也需要耗費許多人力驗證告警是否正确并确認是否需要重新調整門檻值。在攜程,規則告警還涉及了其它問題,比如攜程光公司級别的監控平台就有三個,每個業務部門還會根據自己的業務需求或業務場景建構自己的監控平台。攜程内部有十幾個不同規模的監控平台,在每一個監控平台都配置監控名額對于使用者是非常繁瑣的。
二、Prophet
針對規則告警存在的以上幾種問題,攜程建構了自己的實時智能異常檢測平台——Prophet。攜程建構Prophet的靈感源于FaceBook的Prophet,但實作上有别于FaceBook的Prophet。
1.一站式異常檢測解決方案
首先,Prophet以時間序列類型的資料作為資料輸入。其次,Prophet以監控平台作為接入對象,以去規則化為目标。基于深度學習算法實作異常的智能檢測,基于實時計算引擎實作異常的實時檢測,提供了統一的異常檢測解決方案。

2.Prophet系統架構
- 底層:Hadoop底層。YARN作為統一資源排程的引擎,主要用于運作Flink的作業。HDFS主要用于存儲訓練好的TensorFlow模型。
- 引擎層:首先資料必須實時存在于消息隊列當中,Prophet使用的是Kafka。此外,Prophet使用Flink計算引擎實作實時異常預警,使用TensorFlow作為深度學習模型的訓練引擎。同時Prophet基于時序資料庫存儲曆史資料。
- 平台層:最上層是對外提供服務的平台層Prophet。Clog用于采集作業日志。Muise是實時計算平台。Qconfig用于存儲作業中需要用到的配置項。Hickwall用于作業的監控告警。
3.Why Flink?
目前主流的實時計算引擎有Flink、Storm和SparkStreaming等多種,攜程選擇Flink作為Prophet平台的實時計算引擎的原因主要是Flink具備以下四點特征:
- 高效的狀态管理:異常檢測的過程中有許多狀态資訊需要存儲。使用Flink自帶的State Backend可以很好地存儲中間狀态資訊。
- 豐富的視窗支援:視窗包含滾動視窗、滑動視窗以及其他視窗。Prophet基于滑動視窗進行資料處理。
- 支援多種時間語義:Prophet基于Event Time。
- 支援不同級别的容錯語義:Prophet至少需要做到At Least Once或Exactly Once的級别。
攜程實時智能檢測平台建設實踐
4.Prophet操作流程
使用者隻需要在自己常用的監控平台上選擇配置智能告警,後續所有流程都是由監控平台和Prophet智能告警平台對接完成。監控平台所需要做的包含兩件事,首先将使用者配置的監控名額同步到Prophet平台, 其次監控平台需将使用者配置的監控名額資料實時的推送到Kafka消息隊列中。
Prophet在接受到新的監控名額後,便開始嘗試使用Tensorflow訓練模型。模型訓練需要曆史資料,平台可以按照約定好的規範提供曆史資料查詢接口,Prophet通過接口擷取曆史資料并進行模型訓練、如果沒有接口,Prophet基于消息隊列中的資料來積累訓練資料集。模型訓練完成後,将其上傳到HDFS,Prophet會更新配置中心中的配置通知Flink有新訓練好的模型可以加載。所有實時推送到Kafka裡面的監控名額的數值,會同步的落到Prophet的時序資料庫中,在異常檢測的過程中需要用到這些名額數值。當模型訓練完成後,Flink的作業一旦監聽到配置發生了更新,就開始嘗試加載新模型,實時消費Kafka裡面的名額資料,最終産出檢測結果以及異常告警會回寫至Kafka,各個監控平台會從Kafka擷取自己監控平台的那一部分告警資料。整套Prophet操作流程對于使用者是無感覺的,使用者隻需要配置告警,極大的提供了便捷性。
三、智能化與實時化
1.智能化挑戰
在做智能檢測之前還會遇到一些挑戰。
- 負樣本少:生産環境中發生異常的機率比較小。攜程在很多年的時間僅積累了大概幾千條負樣本資料。
- 業務名額類型多:業務名額類型繁多,有訂單、支付等業務類型的名額,也有服務類型的名額,如請求數、響應延時等,以及硬體設施類型的名額,如CPU、記憶體、硬碟等各種名額。
- 業務名額形态多:正因為有不同類型的業務名額,業務名額的形态也各不相同。攜程将業務名額形态歸納為三部分。一是周期波動相對平穩的名額,第二是穩定的,不會劇烈波動的名額,第三是上下波動幅度非常劇烈、呈現不穩定的形态的名額。
2.深度學習算法選擇
針對以上三點問題,攜程嘗試了RNN,LSTM和DNN等多種深度學習算法。
- RNN:RNN的優點是适合時間序列類型的資料,而缺點是存在梯度消失問題。
- LSTM模型:LSTM的優點是解決了梯度消失的問題。RNN和LSTM深度學習算法需要先給每個名額訓練一個模型,然後輸入目前的資料集,基于模型來預測目前資料集的走向。然後再比對預測資料集和目前資料集進行異常檢測。這種方式帶來的好處是檢測精度高,但是單名額單模型也帶來更多的資源消耗。
- DNN:DNN的優點是單個模型能夠覆寫所有異常檢測的場景。但是特征提取會非常複雜,需要提取不同頻域的特征,需要大量使用者标注資料。
3.離線模型訓練
攜程一般兩周發一次版本,每個業務名額都是每兩周嘗試訓練一次,模型輸入的訓練資料也取兩周的資料集。在使用曆史資料之前需要做資料預處理,比如曆史資料中可能存在null值,需要使用均值标準差将其補齊。其次曆史資料區間裡面肯定會有一些異常區間,需要用一些預測值替換異常區間的異常值。另外由于節假日期間資料較為複雜,需要替換節假日期間的異常值。對曆史資料的資料集做資料預處理之後,開始提取其不同時序的特征或者頻率的特征。然後通過一個分類模型分類出名額是平穩的、非周期的還是周期型的。不同類型的名額需要不同的模型進行訓練。
4.模型動态加載
模型訓練完成後,Flink作業需要動态加載模型。但實際場景下,不可能每訓練一個模型便重新開機一次Flink作業。是以Prophet平台将模型訓練完成後上傳到HDFS,通知配置中心,然後Flink作業開始從HDFS上拉取模型。為了使每個模型均勻分布在不同的Task Manager上面,所有監控名額會根據本身id做keyBy,均勻分布在不同的Task Manager上。每個Task Manager隻加載自己部分的模型,以此降低資源消耗。
5.資料實時消費與預測
模型加載完成後需要做實時異常檢測。首先從Kafka消息隊列中消費實時資料。Prophet目前基于Flink Event Time+滑動視窗。監控名額的時間粒度可以分為很多種,如1分鐘一個點、5分鐘一個點、10分鐘一個點等等。例如基于1分鐘一個點的場景來看,在Flink作業中開一個視窗,其長度是十個時間粒度,即十分鐘。當積累到十條資料時,用前五個資料預測下一個資料,即通過第1、2、3、4、5五個時刻的資料去預測第六個時刻的資料,然後用第2、3、4、5、6時刻的資料預測第七個時刻的資料。最終獲得第6、7、8、9、10五個時刻的預測值和實際值。再利用預測值與實際值進行對比。以上是資料無異常的理想場景下的情況。
6.資料插補與替換
實際場景下往往會出現意想不到的情況。例如上述10分鐘的場景中隻獲得了9條資料,缺少第4個時刻的資料, Prophet會使用均值标準差補齊此類缺失資料。另外如果在上一個時刻檢測到第6、7、8、9、10時間區間是異常區間,發生了下跌或者上升。那麼此區間的資料被認為是不正常的,不能作為模型輸入。此時需要用上一批次模型預測出的第6時刻的值替換原始的第六個時間粒度的值。第2、3、4、5、6這五個時刻值中第4是插補而來的,第6是時間區間訓練出來的預測預測值替換掉了異常值。以插補替換之後的值作為模型輸入,得到新的預測值7。再依次進行預測。中間過程中異常區間第6、7、8、9、10時刻的預測值需要作為一個狀态來存儲到Flink StateBackend,後續視窗會使用到這些預測值。
7.實時異常檢測
實時異常檢測主要可以從以下幾個方面進行判斷:
- 基于異常類型與敏感度判斷:不同的名額不同的異常類型,如上升異常,下跌異常。其次,不同名額敏感度不同,可以定義其為高敏感度、中敏感度、低敏感度。當高敏感度名額發生簡單的下降抖動時,認為是下跌異常。中敏感度名額可能連續下跌兩個點時會判斷異常。對于低敏感度名額,當下跌幅度較大時才會判斷為異常。
- 基于預測集與實際集的偏差判斷:如果預測結果和實際結果偏差較大,認定目前第6、7、8、9、10時刻區間是潛在的異常區間。
- 基于曆史同期資料均值與标準差判斷:同時需要與上周同期的時間進行對比,同一區間的數值偏差較大,則判斷為異常。當異常樣本較多時,可以用簡單的機器學習分類模型通過預測值和實際值做異常判斷。
8.常見場景
- 常見問題:對于使用者來說,監控名額太多,監控的次元也比較多。比如一個名額可能有max、min等不同的統計方式,監控名額的數量就會比較多。其次,使用者能力有限,很難每日檢視監控告警。
- 異常原因:發生異常的原因一般會是技術性問題。如釋出新版本上線時可能存在的bug導緻業務出現下跌。少數的情況是由于外部因素的影響,比如調用外部連結或者服務,外部服務宕掉導緻自己的服務出現問題。
- 解決方案:使用者為Prophet提供的檢測結果進行标注,選擇檢測結果的正确性。使用者的标注資料會用到Prophet以後的模型訓練中用于優化資料集。
9.節假日場景
由于攜程做旅遊方向的業務,節假日期間問題較為突出。不同類型的業務在節假日的表現是不同的。例如攜程的機票、火車票基本是在節前上升到一定量,到假期期間由于人們出遊,該買的票已經購買完成,機票等業務訂單量會下降很多。而酒店等業務在節假期間會上升很多。不同類型業務的趨勢不同,上升幅度較大的業務容易産生漏報,對于下跌幅度較大的業務,容易産生誤報。
節假日應對手段:不同的場景會導緻不同的問題,是以Prophet針對節假日場景做了一些特殊處理。首先,維護每年節假日資訊表,程式一旦發現下一個節假日還有一個星期時,Prophet就會提取出過去兩年内的不同節假日期間的資料。然後計算前兩年的不同節假日和目前節假日數值的相似度來比對。相當于以目前節假日的資料拟合過去節假日的資料,拟合到某個時間段時,就知道大概從某個時間開始到某個時間結束是和目前趨勢類似的。然後會用過去多個節假日的資料作為一個組合作為新模型的資料輸入去訓練資料集。不同節假日的占比不同,通過一些方式計算出不同占比值。最終相基于組合的資料集訓練出新的模型,新的模型可以比較好地預測出某一個名額或者某一個業務在節假期七天之内的趨勢。
10.平台現狀
Prophet基本覆寫了攜程所有業務線。即攜程的重要業務名額基本都已經在使用監控智能告警。業務類型包含7種。監控名額的數量達到10K+,覆寫了攜程所有訂單、支付等重要的業務名額,覆寫了大部分服務的重要的業務名額。接入平台在10+左右,基本接入了攜程公司所有系統級别的監控平台,在陸續接入各個業務部門自己的監控平台。Prophet平台能夠覆寫95%左右的異常,準确報警率達到75%。因為每個資料同步到Prophet便觸發資料實時消費、預測以及告警,告警延遲達到ms級别。告警數量也下降了十倍左右。
四、挑戰與展望
1.挑戰
- 資源消耗大:如果采用LSTM模型,需要為每個名額訓練模型,單個Flink作業裡面都加載了約4K~5K的模型,無論訓練資源還是實時處理資源消耗都相對較大。
- 節假日影響:由于在業務名額在不同節假日的趨勢不同,告警準确性受到一定程度的影響。
- 智能告警無法适用于全部場景:有些機器的CPU的使用率可以直接設定門檻值,達到95%時告警,非常友善簡單。但是如果用智能告警的方式拟合其趨勢,意義不大。另外節假日大促時,會發放門票、酒店優惠券等活動,其訂單量可能快速增長10倍到100倍。這種突發的快速增長在曆史資料也很難學習到。上述場景的資料智能告警比較難處理。
2.展望
針對上述問題,Prophet正陸續進行改進,希望通過下面幾種方式解決遇到的挑戰。
- 通用模型迫在眉睫:Prophet目前訓練了一個DNN模型,可以處理所有監控名額。DNN模型的準确率可能相較于LSTM模型會低一點,但能夠涵蓋較多場景。是以針對訂單、支付等重要的業務名額,可以使用LSTM算法模型,保證準确性,但對于相對不太重要的業務名額,可以使用DNN通用模型。
- 節假日算法上線:Prophet節假日算法已經線上上驗證半年,基本可以保證其準确性。
- 覆寫攜程全部監控平台:Prophet已經覆寫了攜程70%~80%的監控平台。大部分業務名額是在公司的系統監控級别,是以隻要能覆寫公司級别的監控系統,就可以覆寫大部分重要的業務名額。後續,Prophet也将陸續接入更多業務部門的監控平台。