背景
美團點評酒旅運營需求在離線場景下,已經得到了較為系統化的支援,通過對離線資料收集、挖掘,可對目標使用者進行T+1觸達,通過向目標使用者傳送Push等多種方式,在一定程度上提高轉化率。但T+1本身的延遲性會導致使用者在產生特定行為時不能被實時觸達,無法充分發揮資料的價值,取得更優的運營效果。
在此背景下,運營業務需要著手挖掘使用者行為實時資料,如實時瀏覽、下單、退款、搜尋等,對滿足運營需求使用者進行實時觸達,最大化運營活動效果。
業務場景
在運營實時觸達需求中,存在如下具有代表性的業務場景:
- 使用者在30分鐘內發生A行為次數大於等於3次
- 使用者為美團酒店老客,即使用者曾購買過美團酒店產品
- 使用者在A行為前24小時內未發生B行為
- 使用者在A行為後30分鐘內未發生B行為(排除30分鐘內使用者自發產生B行為的影響,降低對結果造成的偏差)
本文以該典型實時運營場景為例,圍繞如何設計出可支撐業務需求高效、穩定執行的系統進行展開。
早期方案
運營實時觸達需求早期活動數量較少,我們通過為每個需求開發一套Storm拓撲相關程式碼、將運營活動規則硬編碼這一“短平快”的方式,對運營實時觸達需求進行快速支援,如圖1所示:
早期方案的問題
早期方案是一種Case By Case的解決方式,不能形成一個完整的系統。隨著實時運營業務開展,相關運營活動數量激增,線上維護著多套相似程式碼,一方面破壞了DRY(Don't Repeat Yourself)原則,另一方面線上維護成本也呈線性增長,系統逐漸無法支撐當前的需求。
挑戰
為解決早期方案中出現的問題,對系統建設提出了以下挑戰:
- 硬編碼活動規則的方式產生了大量重複程式碼,開發成本較高,需求響應時間較長。
- 業務規則修改困難,調整運營活動條件需要修改程式碼並重啟線上拓撲。
- 線上Storm拓撲較多,資源利用率、系統吞吐量低,統一維護成本較高。
- 缺乏完善的監控報警機制,很難早於業務發現系統及資料中存在的穩定性問題。
針對以上挑戰,結合業務規則特點,美團點評資料智慧團隊調研並設計了酒旅運營實時觸達系統。
技術調研
規則引擎的必要性
提高靈活度需要從業務規則和系統程式碼解耦和入手,規則和程式碼耦合直接導致了重複程式碼增多、業務規則修改困難等問題。那如何將業務規則和系統程式碼解耦和呢?我們想到使用規則引擎解決這一問題。
規則引擎是處理複雜規則集合的引擎。通過輸入一些基礎事件,以推演或者歸納等方式,得到最終的執行結果。規則引擎的核心作用在於將複雜、易變的規則從系統中抽離出來,由靈活可變的規則來描述業務需求。由於很多業務場景,包括酒旅運營實時觸達場景,規則處理的輸入或觸發條件是事件,且事件間有依賴或時序的關係,所以規則引擎經常和CEP(複合事件處理)結合起來使用。
CEP通過對多個簡單事件進行組合分析、處理,利用事件的相互關係,找出有意義的事件,從而得出結論。文章最前面背景中提到的業務場景,通過多次規則處理,將單一事件組合成具有業務含義的複合事件,進而提高該類僅瀏覽未下單的使用者的下單概率。可以看出,規則引擎及CEP可以滿足業務場景的具體需求,將其引入可以提高系統面對需求變化的靈活度。
規則引擎調研
在設計規則引擎前,我們對業界已有的規則引擎,主要包括Esper和Drools,進行了調研。
Esper
Esper設計目標為CEP的輕量級解決方案,可以方便的嵌入服務中,提供CEP功能。
優勢
- 輕量級可嵌入開發,常用的CEP功能簡單好用。
- EPL語法與SQL類似,學習成本較低。
劣勢
- 單機全記憶體方案,需要整合其他分散式和儲存。
- 以記憶體實現時間窗功能,無法支援較長跨度的時間窗。
- 無法有效支援定時觸達(如使用者在瀏覽發生後30分鐘觸達支付條件判斷)。
Drools
Drools開始於規則引擎,後引入Drools Fusion模組提供CEP的功能。
優勢
- 功能較為完善,具有如系統監控、操作平臺等功能。
劣勢
- 學習曲線陡峭,其引入的DRL語言較複雜,獨立的系統很難進行二次開發。
- 以記憶體實現時間窗功能,無法支援較長跨度的時間窗。
- 無法有效支援定時觸達(如使用者在瀏覽發生後30分鐘觸達支付條件判斷)。
由於業務規則對時間窗功能及定時觸達功能有較強的依賴,綜合以上兩種規則引擎的優劣勢,我們選用了相對SpEL更為輕量的表示式引擎Aviator,將流式資料處理及規則引擎整合至Storm中,由Storm保證系統在資料處理時的吞吐量,在系統處理資源出現瓶頸時,可在公司託管平臺上調整Worker及Executor數量,降低系統水平擴充套件所需成本。
技術方案
確定引入規則引擎後,圍繞規則引擎的設計開發成為了系統建設的主要著力點。通過使用實時資料倉儲中的使用者實時行為資料,按業務運營活動規則,組合成有意義的複合事件,交由下游運營業務系統對事件的主體,也就是使用者進行觸達。將系統抽象為以下功能模組,如圖2所示:
總體來看,系統組成模組及功能如下:
- 規則引擎:整合於Storm拓撲中,執行運營活動條件轉換成為的具體規則,作出對應響應。
- 時間窗模組:具有可選時間跨度的滑動時間窗功能,為規則判定提供時間窗因子。
- 定時觸達模組:設定規則判定的執行時間,達到設定時間後,執行後續規則。
- 自定義函式:在Aviator表示式引擎基礎函式之上,擴充套件規則引擎功能。
- 報警模組:定時檢查系統處理的訊息量,出現異常時為負責人傳送報警資訊。
- 規則配置控制檯:提供配置頁面,通過控制檯新增場景及規則配置。
- 配置載入模組:定時載入活動規則等配置資訊,供規則引擎使用。
其中,規則引擎由核心元件構成的最小功能集及擴充套件元件提供的擴充套件功能組成。由於規則引擎解耦了業務規則和系統程式碼,使得實時資料在處理時變的抽象,對資料監控、報警提出了更高的要求。下面我們將從規則引擎核心元件、規則引擎擴充套件元件、監控與報警三個方面分別進行介紹。
規則引擎核心元件
規則引擎核心元件為構成規則引擎的最小集合,用以支援完成基礎規則判斷。
規則引擎核心流程
引入規則引擎後,業務需求被轉換為具體場景和規則進行執行,如圖3所示:
規則引擎在執行規則過程中,涉及以下資料模型:
- 場景:業務需求的抽象,一個業務需求對應一個場景,一個場景由若干規則組成。用不同的規則組成時序和依賴關係以實現完整的業務需求。
- 規則:規則由規則條件及因子組成,由路由至所屬場景的事件觸發,規則由規則條件、因子及規則響應組成。
- 規則條件:規則條件由因子構成,為一個布林表示式。規則條件的執行結果直接決定是否執行規則響應。
- 因子:因子是規則條件的基礎組成部分,按不同來源,劃分為基礎因子、時間窗因子和第三方因子。基礎因子來源於事件,時間窗因子來源於時間窗模組獲取的時間窗資料,第三方因子來源於第三方服務,如使用者畫像服務等。
- 規則響應:規則執行成功後的動作,如將複合事件下發給運營業務系統,或傳送非同步事件進行後續規則判斷等。
- 事件:事件為系統的基礎資料單元,劃分為同步事件和非同步事件兩種型別。同步事件按規則路由後,不呼叫定時觸達模組,順序執行;非同步事件呼叫定時觸達模組,延後執行。
時間窗模組
時間窗模組是酒旅運營實時觸達系統規則引擎中的重要構成部分,為規則引擎提供時間窗因子。時間窗因子可用於統計時間視窗內瀏覽行為發生的次數、查詢首次下單時間等,表1中列舉了在運營實時觸達活動中需要支援的時間窗因子型別:
型別 | 示例 | 因子構成 |
---|---|---|
count | 近X分鐘瀏覽POI大於Y次 | count(timeWindow(event.id, event.userId, X * 60)) |
distinct count | 近X分鐘瀏覽不同POI大於Y次 | count(distinct(timeWindow(event.id, event.userId, X * 60))) |
first | 近X天支付的首單酒店 | first(timeWindow(event.id, event.userId, X * 60)) |
last | 近X天最後一次搜尋的酒店 | last(timeWindow(event.id, event.userId, X * 60)) |
表1 時間窗因子型別
根據時間窗因子型別可以看出,時間窗因子有以下特點:
- 時間窗儲存中需要以List形式儲存時間窗詳情資料,以分別支援聚合及詳情需求。
- 時間窗因子需要天粒度持久化,並支援EXPIRE。
- 時間窗因子應用場景多,是許多規則的重要組成因子,服務承受的壓力較大,響應時間需要在ms級別。
對於以上特點,在評估使用場景和接入資料量級的基礎上,我們選擇公司基於Tair研發的KV的儲存服務Cellar儲存時間窗資料,經測試其在20K QPS請求下,TP99能保證在2ms左右,且儲存方面價效比較高,可以滿足系統需求。
在實際運營活動中,對時間窗內使用者某種行為次數的判斷往往在5次以內,結合此業務場景,同時為避免Value過大影響讀寫響應時間,在更新時間窗資料時設定閾值,對超出閾值部分進行截斷。時間窗資料更新及截斷流程如圖4所示:
文章最前面背景中提到的業務場景,在1. 使用者在30分鐘內發生A行為次數大於等於3次
、3. 使用者在A行為前24小時內未發生B行為
、4. 使用者在A行為後30分鐘內未發生B行為(排除30分鐘內使用者自發產生B行為的影響,降低對結果造成的偏差)
中,均使用了時間窗模組對滑動時間窗內的使用者行為進行了統計,以時間窗因子作為規則執行判斷的依據。
規則引擎擴充套件元件
規則引擎擴充套件元件在核心元件的基礎上,增強規則引擎功能。
自定義函式
自定義函式可以擴充Aviator功能,規則引擎可通過自定義函式執行因子及規則條件,如呼叫使用者畫像等第三方服務。系統內為支援運營需求擴充套件的部分自定義函式如表2所示:
名稱 | 示例 | 含義 |
---|---|---|
equals | equals(message.orderType, 0) | 判斷訂單型別是否為0 |
filter | filter(browseList, 'source', 'dp') | 過濾點評側瀏覽列表資料 |
poiPortrait | poiPortrait(message.poiId) | 根據poiId獲取商戶畫像資料,如商戶星級屬性 |
userPortrait | userPortrait(message.userId) | 根據userId獲取使用者畫像資料,如使用者常住地城市、使用者新老客屬性 |
userBlackList | userBlackList(message.userId) | 根據userId判斷使用者是否為黑名單使用者 |
表2 自定義函式示例
文章最前面背景中提到的業務場景,在2. 使用者為美團酒店老客,即使用者曾購買過美團酒店產品
中,判斷使用者是否為美團酒店老客,就用到了自定義函式,呼叫使用者畫像服務,通過使用者畫像標籤進行判定。
定時觸達模組
定時觸達模組支援為規則設定定時執行時間,延後某些規則的執行以滿足運營活動規則。文章最前面背景中提到的業務場景,在4. 使用者在A行為後30分鐘內未發生B行為(排除30分鐘內使用者自發產生B行為的影響,降低對結果造成的偏差)
條件中,需要在A行為發生30分鐘後,對使用者是否發生B行為進行判定,以排除使用者自發產生B行為對活動效果造成的影響。
定時觸達模組涉及的資料流圖如圖5所示:
早期的業務需求對延遲時間要求較短,且活動總數量較小,通過維護純記憶體DelayQueue的方式,支援定時觸達需求。隨著相關運營活動數量增多及定時觸達時間的延長,純記憶體方式對記憶體的佔用量越來越大,且在系統重啟後定時資料會全部丟失。在對解決方案進行優化時,瞭解到公司訊息中介軟體組在Mafka訊息佇列中支援訊息粒度延遲,非常貼合我們的使用場景,因此採用此特性,代替純記憶體方式,實現定時觸達模組。
監控與報警
對比離線資料,實時資料在使用過程中出現問題不易感知。由於系統針對的運營活動直接面向C端,在出現系統異常或資料質量異常時,如果沒有及時發現,將會直接造成運營成本浪費,嚴重影響活動轉化率等活動效果評估指標。針對系統穩定性問題,我們從監控與報警兩個角度入手解決。
監控
利用公司資料平臺現有產品,對系統處理的實時事件按其事件ID上報,以時間粒度聚合,資料上報後可實時檢視各類事件量,通過訊息量評估活動規則和活動效果是否正常,上報資料展示效果如圖6所示:
報警
監控只能作為Dashboard供展示及檢視,無法實現自動化報警。由於用於監控所上報的聚合資料儲存於時序資料庫OpenTSDB中,我們基於OpenTSDB開放的HTTP API,定製報警模組,定時排程、拉取資料,對不同事件,按事件量級、活動重要性等指標,應用環比、絕對值等不同報警規則及閾值。超出設定閾值後,通過公司IM及時傳送報警資訊。如圖7所示,該事件環比出現資料量級下降,收到報警後相關負責人可及時跟蹤問題:
總結與展望
酒旅運營實時觸達系統已上線穩定執行一年多時間,是運營業務中十分重要的環節,起到承上啟下的作用,在系統處理能力及對業務貢獻方面取得了較好的效果:
- 平均日處理實時訊息量近10億。
- 峰值事件QPS 1.4萬。
- 幫助酒店、旅遊、大交通等業務線開展了豐富的運營活動。
- 對轉化率、GMV、拉新等指標促進顯著。
當前系統雖然已解決了業務需求,但仍存在一些實際痛點:
- 實時資料接入非自動化。
- 規則引擎能力需要推廣、泛化。
- 場景及規則註冊未對運營PM開放,只能由RD完成。
展望未來,在解決痛點方面我們還有很多路要走,未來會繼續從技術及業務兩方面入手,將系統建設的更加易用、高效。
作者簡介
曉星,美團平臺技術部-資料中心-資料智慧組系統工程師,2014年畢業於北京理工大學,從事Java後臺系統及資料服務建設。2017年加入美團點評,從事大資料處理相關工作。
偉彬,美團平臺技術部-資料中心-資料智慧組系統工程師,2015年畢業於大連理工大學,同年加入美團點評,專注於大資料處理技術與高併發服務。
招聘
最後發個廣告,美團平臺技術部-資料中心-資料智慧組長期招聘資料探勘演算法、大資料系統開發、Java後臺開發方面的人才,有興趣的同學可以傳送簡歷到lishangqiang#meituan.com。
如果對我們團隊感興趣,可以關注我們的專欄。