Flink CEP 在抖音電商的業務實踐

ApacheFlink發表於2023-02-10

摘要:本文整理自抖音電商實時數倉研發工程師張健,在 FFA 實時風控專場的分享。本篇內容主要分為四個部分:


  1. Flink CEP 簡介

  2. 業務場景與挑戰

  3. 解決方案實踐

  4. 未來展望


Tips:點選「閱讀原文」檢視原文影片&演講 ppt

01

Flink CEP 簡介


Flink CEP 在抖音電商的業務實踐

Flink CEP 是基於 Flink Runtime 構建的複雜事件處理庫,它擅長處理跨多個事件的複雜規則匹配場景。例如檢測使用者下單後,是否超過半個小時沒有發生支付行為;檢測使用者進入直播間後,是否有瀏覽商品隨後加入購物車行為。


Flink CEP 有以下優勢:

  • 支援跨多事件的規則匹配計算;

  • 支援精準一次計算語義;

  • 低延遲、高吞吐等特性。


02

業務場景與挑戰


隨著抖音電商業務逐漸趨於穩定和成熟,抖音電商實時數倉團隊接到的實時資料規則類業務需求也逐步增多,因此我們開始嘗試使用 Flink CEP 來支援這些業務場景。

下面列舉兩個典型的業務場景,並介紹一下 Flink CEP 在這些場景中遇到的一些挑戰。


2.1 業務背景


Flink CEP 在抖音電商的業務實踐

第一是實時預警場景,它是非常典型的業務訴求,把使用者看資料的方式從大屏“盯盤”轉換為“根據規則檢測結果,主動推送”,這無疑對一些關鍵業務問題的發現和洞察起到至關重要的作用。有如下三個具體案例:


  • 直播實時檢測場景。當檢測到 10 分鐘內觀看人數持續下跌的直播間時,實時把訊息推送給直播達人,方便其及時做出直播策略的調整。比如調整講解商品的話術,發放粉絲禮物等等,進而提升轉化。


  • 實時風控的場景。當檢測到有使用者 30 分鐘內建立了多筆訂單,均未支付的情況,這個使用者大機率是一個刷單使用者。我們會將這個使用者實時推送給平臺治理同學,並做出相應的封禁處置,促進平臺的整體生態健康。


  • 售後諮詢場景。當檢測到一個使用者發起諮詢後,超過 30 分鐘都未得到回覆,會立即通知相關的客服人員及時回覆,提升整體的使用者體驗。


第二是實施營銷場景,它是基於實時資料驅動,根據定義的規則策略挖掘目標群體,並根據業務目標做出精準營銷投放的營銷活動。有如下三個具體案例:


  • 實時發券場景。針對一些價格比較高的商品,當檢測到使用者下單後超過 30 分鐘沒有支付,那麼該使用者很有可能是覺得價格太高,所以一直猶豫要不要支付。這個時候可以及時給這個使用者發放一些優惠券刺激購買,從而提升平臺的轉化率。


  • 幫助商家及時發現爆款商品場景。當檢測到某款商品在五分鐘內成交超過 1000 單時,會實時將這個商品的名稱、品牌、庫存等資訊推送給商家,以便商家及時補貨、直播間掛連結等行為,提升運營效率。


  • 線上發獎勵場景。當檢測到一個達人在完成電商大學學習後,一天內進行了電商開播或者釋出了電商短影片等行為,就會對這個達人發放抖 dou+券等儀式獎勵,提升整體達人的入駐率,進而給商家提升更加多元的達人選擇。


2.2 業務挑戰


Flink CEP 在抖音電商的業務實踐

第一,在規則配置方面存在靈活性不足的問題。當前無論是新增還是修改規則,都需要實時數倉的研發同學透過修改程式碼的方式來支援,這就導致研發同學需要頻繁的對接業務。在一些極端的場景,比如雙十一大促期間,一個研發同學往往需要同時應對接,二十多個運營同學的規則建立或者修改的訴求。業務需求也由於人力的單點阻塞問題遲遲無法上線。


第二,規則與計算任務之間存在深度耦合。當每個規則都需要強制繫結一個計算任務時,就會導致計算任務的數量會隨著規則的建立逐漸增多。大量的任務會造成極高的運維成本和巨大的資源浪費,使整個系統最終變得不可維護。以前面提到的商家自定義規則檢測爆款商品的這個場景為例,考慮到當前抖音電商龐大的商家群體,最終建立規則的數量可能是巨大的,進而導致整個計算任務的數量也隨之爆炸。


第三,當前 Flink CEP 支援的規則語義不夠豐富。列舉兩個典型的案例:


  • 第一個案例,假設我們需要檢測使用者多次下單後,沒有在一小時內完成支付行為。這種場景的特點是使用者最後一次下單後,一直沒有支付事件來觸發這個規則完成匹配。當前 Flink CEP 不支援這種場景,但在真實的業務中這又是非常普遍的規則訴求。


  • 第二個案例,假設我們需要檢測使用者在過去一小時內,是否完成瀏覽商品、加入購物車、下單行為。注意這裡要求的三種行為不分先後順序,只要在規定的時間內完成以上三種行為即可。這種場景當前 Flink CEP 也不支援。


03

解決方案實踐


Flink CEP 在抖音電商的業務實踐

整體我們分為四個階段來解決上述的問題。

第一階段,我們對 Flink CEP 規則的核心資訊進行了提煉和抽象,並設計了一套清晰易懂的規則 DSL。這樣就可以讓業務同學自主配置業務規則,從而解決規則配置靈活性不足的問題。那麼如何讓業務配置的規則執行起來?


第二階段,我們對 Flink CEP 計算任務進行改造,讓其支援動態提交規則或者更新規則的能力,從而實現規則與計算任務之間的徹底解耦。解耦之後,不再強制要求每一個規則必須對應一個計算任務來執行。也就是同一個計算任務可以同時接收提交的多條規則,實現收斂整體計算任務的數量,提升規則利用率的目標。

前面兩個階段要解決了規則配置的靈活性以及規則與其他任務的強繫結問題,但是仍然沒有解決規則本身的語義豐富性問題。因此,第三階段,我們主要針對特定業務的場景的規則訴求、升級和擴充規則的語義。

經過前三階段的升級和最佳化,前面提到的業務痛點已經基本得到了解決,但規則引擎在易用性和周邊能力方面還有所欠缺。例如我們無法直觀的檢視當前系統執行的規則內容、註冊事件資料;業務提交的規則與計算任務之間根據什麼樣的策略來進行分發;使用者仍然需要訂閱規則引擎的輸出資料進行格式轉換、寫入目標儲存等操作。


因此在第四階段,我們整合了前面的方案,並不斷豐富周邊能力生態,打造了一站式實時規則平臺。支援使用者在平臺上進行事件註冊、預覽、規則配置、規則除錯、規則釋出等全流程的自主操作,進一步提升工作效率。


Flink CEP 在抖音電商的業務實踐

為了實現業務自主配置規則,規則的語法必須清晰易懂。我們設計規則 DSL 整體結合了 JSON 和基礎 SQL 語法,利用 JSON 的高可讀性來描述規則的後設資料、規則匹配屬性等資訊,利用 SQL 的強大表達力來描述 CEP 匹配條件以及匹配結果的處理邏輯。


Flink CEP 在抖音電商的業務實踐

這裡我們發現了一個新的問題,如何透過 SQL 來表達事件是否滿足匹配條件?SQL 可以查詢哪些表?以一個具體的案例來回答這個問題。


假設要檢測使用者下單後是否發生了支付行為,那麼規則編譯生成的 NFA 可能是上圖所示的樣子。在規則執行時,我們將當前流入的事件以及當前規則的中間匹配結果,都以資料表的形式註冊到上下文。當前流入的事件對應的表名稱預設是 events,規則中間匹配結果對應的表名稱和它的 PatternName 保持一致。


在這個案例中,每個 SQL 可查詢到的表就是三張,分別是 events 表,表示當前流入的事件;create_order 表,表示當前已經匹配到的下單事件;pay_order 表,表示已經匹配到的支付事件。


在配置 SQL 時,就可以對已經註冊到上下文的任意資料表進行查詢。當 SQL 查詢的結果非空時,就表示當前匹配條件判斷透過。狀態機經過 Take 邊流轉到下一個狀態,並將事件儲存到對應的表,否則就會到 Ignore 邊,丟棄掉事件。


Flink CEP 在抖音電商的業務實踐

再來看一下這個案例對應的規則配置條件的完整配置。整體是一個陣列的形式,陣列中每個元素表示一個 pattern,第二個 pattern 與前一個 pattern 之間的連線型別是 FOLLOWED_BY。第一個 pattern 的匹配條件是從流中檢測使用者下單事件,第二個 pattern 匹配條件是從流入檢測使用者支付事件。


注意,這個支付事件的訂單是上一步我們快取下來的下單事件對應的那個訂單。經過上面的改造實現了,只要稍微有一些 SQL 基礎的業務人員,都可以看懂並配置規則。


Flink CEP 在抖音電商的業務實踐

前面我們提到,當前的 Flink CEP 計算任務不支援動態提交規則。主要原因是在編譯階段 Flink CEP 規則計算邏輯就確定了,並且已經透過 NFACompiler 編譯完畢。在執行時計算任務只能固定執行之前已經編譯好的規則。那麼我們是如何改造的呢?


Flink CEP 在抖音電商的業務實踐

為了實現規則的動態發現,我們引入了一個規則流,使用者提交或修改的規則都可以發到這條流中。為了實現規則的動態注入,我們將規則流設計為 Broadcast Stream。當發現新提交的規則時,廣播分發到所有的 SubTask。


為了實現規則的線上載入執行,我們基於前面提到的規則 DSL,研發了一套基於規則的解析器。當 SubTask 收到分發的規則後,可以線上解析生成規則執行需要的元件。例如 NFA、規則匹配條件 SQL 對應的執行計劃、匹配結果處理函式等。然後儲存到 Flink State 中,持續檢測和處理後續的事件。


解釋一下為什麼採用 Broadcast Stream 來實現規則的動態注入。由於 Flink CEP 是有狀態的計算,規則的更新/刪除往往需要伴隨 Flink States 的操作和處理。例如:當刪除規則時,連帶當前規則關聯的事件快取等狀態資訊也需要一併刪除。對比透過其他方式感知規則變更,比如啟動一個非同步執行緒定時掃描規則,透過 Broadcast Stream 的方式優勢是,當檢測到規則變更,能夠更方便安全的操作 Flink State。


上面的方案解決了一個計算任務動態提交規則的訴求,但當一個計算任務執行多條規則時,又帶來了一個新的問題。


問題一,由於規則的事件分組邏輯可能不同。(比如規則 A 需要先對事件流按照"使用者的 IP 地址"路由到同一 Task 後再進行 NFA 匹配計算。而規則 B 則需要對事件流按”使用者的裝置 ID“進行路由)。那麼當這兩個規則執行在同一個計算任務時,如何相容呢?


為了解決這個問題,我們新增了 KeyGenOperator 運算元。當檢測到新的事件流入時,先根據每一條規則配置生成一個與之對應分組的 Key,然後按分組 Key 再進行下游的 Task 分發,這樣就實現了對多條規則的不同事件分組邏輯的相容。


問題二,由於同一個計算任務執行多條規則,就可能會帶來規則計算冗餘的問題。比如,規則 A 關注使用者下單、支付等支付相關事件,而規則 B 關注使用者的商品瀏覽、評論等流量相關的事件。如果同一個計算任務同時執行這兩條規則,那麼這個任務就必須同時消費這兩類事件。也就是說規則 A 本不關注流量類的事件,但由於整個任務整體訂閱了這類事件,就導致規則 A 也必須處理這類事件。


為了解決上述問題,我們在 KeyGenOperator 運算元新增了“事件篩選”元件,實現針對同一輸入事件不同規則裡的個性化事件篩選。也就是說,針對新流入的事件,僅當規則關注這個事件的時候,才會生成與之對應的分組 Key,並且進行後續的計算。


值得一提的是:在商家自定義預警的業務場景中,由於事件篩選的效果是比較好的(也就是說,商家自定義的每個規則僅關注當前商家所屬商品的相關事件),那麼經過我們測試,單個任務(在 600Core、800 併發度的情況下)可以支援的商家簡單規則數量可以超過百萬。


Flink CEP 在抖音電商的業務實踐

當發生事件 A 後一段時間內,沒有發生事件 B,其對應的虛擬碼可能是上面的這種形式。當前的 Flink CEP 不支援這種語義,因為可能造成沒有事件觸發這條規則,最終完成匹配的情況。


Flink CEP 在抖音電商的業務實踐

針對這個問題,我們在規則生成的 NFA 中引入一種 Pending 狀態。當流入事件滿足建立訂單的條件之後,狀態會隨之遷移到 Pending 狀態等待超時。當 Flink CEP 任務的 watermark 向前推進時,會觸發 Pending 狀態的 NFC 進行計算,判斷是否已經超時,如果超時就會觸發 NFA,遷移到下一個 Final 狀態。如果在這之前系統流入了訂單支付事件,就會轉移到 Stop 狀態。


透過這種方式,我們實現了對發生事件 A 之後一段時間內,沒有發生事件 B 類的語義的支援。


Flink CEP 在抖音電商的業務實踐

為了進一步提升規則引擎的應用性,我們整合前面的方案,擴充規則引擎的周邊能力,研發了一站式規則平臺。使用者可以在平臺上自助進行事件的註冊、預覽、規則配置、除錯、釋出等全流程的自助操作。


平臺整個架構共分為四層,分別是:


事件層,例如看播事件、下單事件、物流事件、客服事件等。


計算層,負責動態的接收使用者提交的 CEP 規則,並對規則進行解析,檢測後續流入事件。計算層的核心是規則計算模組,也就是具體的 Flink CEP 計算任務。同時在計算層還有規則排程模組和規則解析模組,規則排程模組負責將新提交的規則分發到具體的 Flink CEP 計算任務,排程策略可以選擇同事件源優先或者負載均衡優先。


  • 同事件源優先是將關注相同 topic 的事件的規則,調動到同一個 Flink CEP 計算任務。例如將關注看播事件的規則排程到一個計算任務中,而將關注物流事件的規則排程到另一個計算任務中。負載均衡優先則是根據 Flink CEP 計算任務當前的負載情況,儘量將新提交的規則排程到相對空閒的計算任務執行。


  • 規則解析模組負責當集團任務收到規則之後,解析並編譯規則,生成規則執行時的元件。例如前面提到的 NFA、規則匹配條件對應的 SQL 執行計劃等等。


觸達層,負責計算層規則匹配結果的資料應用,主要包括延遲策略管理、維度欄位擴充、推送目標管理等。


  • 延遲策略管理主要負責當目標完成匹配後,是否立即進入下一個動作。例如,當使用者完成既定的行為動作之後,可以選擇立即發放優惠券,或者等待五分鐘之後再發放優惠券。


  • 維度欄位擴充主要負責當目標完成匹配後,為資料補充相關的維度欄位。例如,當使用者完成瀏覽、下單、支付行為後,我們可以根據平臺的配置,拼接補充訂單關聯的商品資訊。例如商品的名稱、價格等,供使用者最終更好的決策。


  • 推送目標管理主要負責當目標完成匹配後,具體需要執行的動作。例如當檢測到使用者有可能存在刷單行為時,給平臺治理同學推送飛書訊息。


平臺層,負責與使用者互動以及任務運維等工作。


Flink CEP 在抖音電商的業務實踐

業務成效方面:


  • 業務自主配置規則,提升需求支援靈活性。目前共建立各類實時規則 2.5w+,服務平臺運營同學 100+。


  • 規則與計算任務解耦,無需研發介入即可支援規則建立/變更。業務規則需求支援平均耗時由 1day 縮減至 1hour。


  • 提升 CEP 規則語義豐富度。規則引擎能力實現了抖音電商 70%+ 業務場景的覆蓋。


技術成效方面:


  • 由 Case By Case 的點狀需求支援模式向面向平臺的例行迭代轉變,避免了單點人力阻塞問題,提升整體程式碼健壯性。


  • 整體計算任務數量得到收斂,當前總體任務數量≤50,月均計算任務治理運維相關工作量降低50%+。


  • 降低計算任務整體資源浪費,單任務平均資源利用率提升 50%+。


04

未來展望


未來我們計劃在以下三個方面繼續對規則引擎進行建設。


  • 第一,繼續打磨實時規則平臺周邊生態能力,實現更豐富、靈活的事件接入、觸達方式。


  • 第二,探索規則計算流批一體,打破離線、實時事件之間的壁壘,擴充平臺應用範圍。


  • 第三,打通公司大資料研發環境,實現更加便捷的計算任務操作,進一步降低人工成本。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2934757/,如需轉載,請註明出處,否則將追究法律責任。

相關文章