本文由攜程技術團隊撰寫,介紹了攜程自研的國際業務動態實時標籤處理平臺。其中標籤持久化的場景需要解決業務標籤的持久化儲存、更新、查詢服務,TiDB 通過對於不同場景查詢特性的支援滿足了不同業務場景訪問業務特徵資料的需要。
作者介紹
Weiyi,攜程資深資料開發,關注大資料相關技術,對大資料實時計算、流批一體等方面有濃厚興趣;
Hzhou,攜程資深資料開發,關注大資料相關技術,對系統架構和實時處理等方面有濃厚興趣;
Rongjun,攜程大資料架構開發,專注離線和實時大資料產品和技術。
背景
在國際業務上,因為面臨的市場多,產品和業務複雜多樣,投放渠道多,引流費用高,因此需要對業務和產品做更精細化的管理和優化,滿足市場投放和運營的需要,降低成本,提升運營效率,提升轉化率。為此我們提出研發攜程國際業務動態實時標籤處理平臺(以下簡稱CDP),為 Trip 業務增長解決 “Grow Revenue” 和 “Reduce Costs” 的問題,具體如圖 1-1。
圖 1-1 CDP 所需要解決的業務問題
因為 Trip 資料來源比較廣泛,既有自身資料也有外部資料;資料形式也非常多樣化,既有結構化資料,也有半結構化和非結構化資料;資料加工形式既有離線資料處理,也有線上資料處理;如何通過系統加工這些資料形成業務系統、運營、市場需要並且可以理解的資料和標籤,成為了 CDP 平臺急需解決的業務和系統問題,簡單總結下來系統主要需要解決以下四個方面的問題:
資料採集與管理
主要豐富不同的資料來源,包括三個部分。第一方資料,來自自己,UBT 日誌,平臺資料,客服處理資料,APP 安裝資料。第二方資料,來自集團中的其他品牌的資料,如 SC、Travix 等。第三方資料,來自我們合作方的網站,比如 meta 投放平臺等。
ID 匹配
不同的資料來源有不同的 ID 標籤,比如 APP 端來源的資料會有一個統一的 ClientID 的主鍵,與之相關聯的會有一組標籤。來自不同業務系統的資料都會有對應的 ID 以及標籤與之對應。這些標籤主體的 ID 分別來源於不同的系統和平臺。平臺之間的 ID 有的相互之間可能沒有關聯關係,有的有一定的關聯關係,但不是一一對應的,但是業務系統使用時往往是需要相互組合使用。因此需要有一個 ID 從資料採集到業務標籤建立,到最終使用都能串聯的一個唯一 ID。這個是最大的難點。如果沒有,那我們需要一個非常完整的 ID Mapping,在不同的 ID 之間可以做轉換,這樣使用者可以串聯不同實體之間的標籤。
業務標籤模型
一些有場景決策使用的標籤,比如市場最受歡迎產品,最熱門旅遊目的地等等。很多公司早期在做標籤時什麼都想要,鋪了上百個統計類標籤,然而這些標籤並不能直接使用。而且將上百個標籤砸向產品或運營人員的時候,因為沒有重點,會一下將業務人員“砸暈”。所以能提供真正有效的標籤很重要。在這個過程中對業務的理解就變得尤為重要,系統需要根據業務場景建立對應的業務標籤模型。
標籤的使用
和使用標籤的系統做對接,比如訊息系統,第三方平臺,站內平臺。讓這些業務標籤,最大化幫助業務產生業績。其中的難點是,CDP 怎麼和使用它的平臺去做對接。
要解決以上問題,系統必須提升資料處理能力,因為處理好的資料是需要立馬運用到業務系統、EMD、PUSH 等等使用場景中去,對資料處理系統的時效性、準確性、穩定性以及靈活性等提出了更高的要求。
在過去我們現有 CRM 資料是通過數倉 T+1 計算,匯入到 ES 叢集儲存,前端通過傳入查詢條件,組裝 ES 查詢條件查詢符合條件的資料。目前已經上線的標籤有上百個,有查詢使用的超過 50%,能滿足一部分對資料時效性要求不高的標籤資料篩選場景的需要,比如市場活動目標使用者的選擇。因為是離線計算,所以資料時效性差,依賴底層離線平臺的計算,依賴 ES 的索引,查詢響應速度比較慢。
基於以上這些問題,新系統希望在資料處理過程中能提升資料處理的時效性同時滿足業務靈活性的要求,對於資料處理邏輯,資料更新邏輯,可以通過系統動態配置規則的方式來消費訊息資料(Kafka 或者 QMQ)動態更新標籤,業務層只需要關心資料篩選的邏輯,以及條件查詢。
二、系統設計
基於業務需要,我們將業務資料標籤篩選的場景分為兩大類:
實時觸發場景
根據業務需要,配置動態規則,實時訂閱業務系統的變更訊息,篩選出滿足動態規則條件的資料,通過訊息的方式推送到下游業務方。
標籤持久化場景
將業務系統的實時業務變更訊息按照業務需要加工成業務相關的特徵資料持久化儲存到儲存引擎,業務根據需要組裝查詢條件查詢引擎資料,主要是 OLAP(分析類)和 OLTP(線上查詢)兩大類查詢。
為了解決以上問題,我們設計開發了一套“實時動態標籤處理系統”,業務方只需要按照基本運算元規則配置提交任務,系統就會自動解釋執行規則,按照配置要求執行資料處理操作,目前支援的基本運算元有Stream(流式資料接入目前支援 QMQ 和 Kafka)、Priority(優先順序判斷)、Join、Filter(過濾)、Sink(資料輸出,目前支援 TiDB、Redis、QMQ)等等,這些在整體設計裡面會詳細介紹,通過規則和動態計算的方式提升資料處理和開發效率,降低開發成本。
流式資料採用類 Kappa 架構,標籤持久化採用類 Lambda 架構,系統架構如
圖 2-1。
圖 2-1 CDP 系統架構
系統對公司內輸出主要是對接站內的自運營渠道,比如訊息系統,傳送簡訊,郵箱,廣告。站內主流程根據 CDP 的特徵組裝前端業務流程。
三、實時觸發
針對動態觸發的場景需要解決動態規則配置,規則解析,規則內動態計算節點(運算元,之後都簡稱為運算元)的生成,運算元的相互依賴關係(DAG),以及資料 join 的處理。
為了解決實時流式資料處理,我們引入了類似於 Kappa 架構的資料處理方式,做了一些調整,採用主動 Push 方式,因為這個場景的資料主要是應用於 Push/EDM 等主動觸達的場景,結果資料不需要落地,我們直接通過 QMQ 訊息渠道推送到應用訂閱的訊息佇列。
圖3-1 Kappa 資料處理架構
這樣解決了訊息時效性的問題,同時也解決了規則時效性的問題,修改規則不需要重啟任務即可生效。計算結果採用主動推送的方式,省去了資料儲存和查詢的過程,提升了資料的時效性,節省了儲存空間。
圖 3-2 CDP 實時觸發資料處理架構
規則引擎設計採用Json格式傳參,運算元設計為兩層,上層為固定業務邏輯支援的動態業務運算元,主要包含 Stream、Priority、Join、Filter、Sink,下層為固定業務運算元使用的一些基礎運算元,可以自由組合,以滿足訊息實時處理業務邏輯處理的需要。
關於規則引擎所涉及的一些基本概念描述如下:
Stream
訊息源接入,主要是 Kafka 和 QMQ,結構化 Json 資料,所有的接入訊息源的資料結構、資料型別、來源都需要錄入管理,借用公司的 Kafka 和 QMQ 訊息註冊管理機制,實現全流程打通。
Priority
優先順序判斷,比如主流程一般按照搜尋頁,列表頁,填寫頁,支付頁次序排列,因為流量是一層一層減少,所以越到後面流量越重要,在一些業務場景中需要根據這些流量的重要程度排序,優先順序判斷可以滿足這些業務場景的需要。
Join
Join 運算元,目前只支援使用 Redis 作為 Join 右表,如果 Join 條件不滿足右表資料都為 NULL,預設輸出左表資料,如果需要右表資料需要指定輸出的欄位。
Filter
過濾運算元,可以直接過濾上游資料,也可以過濾上游資料與 Redis Join 後的資料。只有通過的資料才會流入後面運算元,否則該條資料處理結束。
Sink
計算結果輸出,支援配置化方式,目前支援訊息佇列模式(QMQ),資料庫(TiDB、MySQL 等等)。
基礎運算元
基礎的原子運算元,不可再拆分,如 +、-、*、/、>、<、=、>=、<= 以及in,not in,like,rlike,IS_NULL,IS_NOT_NULL 等。
自定義函式
支援計算過程中使用自定義函式,使用者可以自定義資料處理函式並註冊到生產系統,目前支援的函式如下:
字串函式:CONCAT、CONCAT_WS、HASH、IFNULL、IS_NOT_BLANK、IS_NOT_NULL、IS_NULL、LIKE、LOWER、UPPER、REGEXP、REPLACE、SUBSTR、UPPER、URL_EXTRACT_PARAMETER等
時間函式:CURRENT_TIMESTAMP、FROM_UNIXTIME
JSON 函式:JSON_EXTRACT
DAG
DAG 是一種“圖”,圖計算模型的應用由來已久,早在上個世紀就被應用於資料庫系統(Graph databases)的實現中。任何一個圖都包含兩種基本元素:節點(Vertex)和邊(Edge),節點通常用於表示實體,而邊則代表實體間的關係。
由於 DAG 計算是一套非常複雜的體系,我們主要借鑑了 Spark 的 DAG 計算思想,簡化了 DAG 計算流程從而滿足我們實時計算業務場景的需要,在介紹 DAG 計算方式之前,先介紹一下 Spark 中 DAG 計算的基本思想和概念。
在 Spark 中 DAG 是分散式計算模型的抽象,專業術語稱之為 Lineage —— 血統,RDD 通過 dependencies 和 compute 屬性構成首尾相連的計算路徑。
Dependencies 分為兩大類,Narrow Dependencies 和 Wide Dependencies(如圖 3-3)。
Narrow Dependencies 是指父 RDD 的每一個分割槽最多被一個子 RDD 的分割槽所用,表現為一個父 RDD 的分割槽對應於一個子 RDD 的分割槽或多個父 RDD 的分割槽對應於一個子 RDD 的分割槽,也就是說一個父 RDD 的一個分割槽不可能對應一個子 RDD 的多個分割槽。
Wide Dependencies 是指子 RDD 的分割槽依賴於父 RDD 的多個分割槽或所有分割槽,也就是說存在一個父 RDD 的一個分割槽對應一個子 RDD 的多個分割槽。在 Spark裡面需要shuffle,Spark稱之為Shuffle Dependency,做為劃分 stage 依據。
圖 3-3 Narrow Dependencies 與 Wide Dependencies
在 Spark 中 Stage 劃分方式是從後往前推算,遇到 ShuffleDependency 就斷開,遇到 NarrowDependency 就將其加入該 stage。每個 stage 裡面 task 的數目由該 stage 最後一個 RDD 中的 partition 個數決定。如圖 3-4。
圖 3-4 Spark Stage 劃分方式
在 Spark 中 RDD 的運算元分為兩大類:
Transformations:資料轉換,如map、filter、flatMap、join、groupByKey、reduceByKey、sortByKey、repartition等等,該型別運算元採用 lazy evaluation(惰性求值),即 Transformation 操作不會開始就真正的計算,只有在執行 Action 操作的時候 Spark 才會真正開始計算。轉化操作不會立刻執行,而是在內部記錄下所要執行的操作的相關資訊,必要時再執行。
Actions:資料物化操作,計算觸發,如collect、count、foreach、first、saveAsHadoopFile 等等。
每個 Stage 內包含一組 TaskSet,Task 之間傳遞資料是 Pipeline 的方式。
根據業務標籤資料處理需要,借鑑 Spark 的思想,CDP 對 DAG 計算做了一些簡化,具體如下:
在 CDP 的 DAG 中,DAG 的拆分是直接從前往後推算,不需要拆分 Stage,所有的 DAG Task 都在同一個 stage 中(All in one Stage)如圖 3-5,並且是併發可擴充套件,不需要 DAGScheduler。
在 CDP 中運算元分為兩大類:
Operator:資料處理操作運算元,如 Stream、Priority、Join、Filter、Sink,是由基礎的原子運算元配置而來,該型別運算元採用 eagerevaluation(及早求值),即 Operator 在資料一旦進入就會觸發資料處理操作,這樣不需要快取狀態資料,能有效提升資料處理效率。
Edge:描述 Operator 之間的關係,即拓撲關係。
圖 3-5 CDP All in one Stage
四、標籤持久化
標籤持久化的場景需要解決業務標籤的持久化儲存、更新、查詢服務,採用分散式高可用關係型資料庫(TiDB)儲存業務持久化的標籤,採用實時觸發場景中的動態規則配置的方式消費業務系統資料變更訊息,使用本文第三節中提到的實時觸發的方式處理後更新持久化標籤儲存資料,保證業務持久化標籤的時效性,通過 TiDB 對於不同場景查詢特性(主要是 OLAP 和 OLTP)的支援來滿足不同業務場景訪問業務特徵資料的需要。
為了解決標籤持久化場景的需求,借鑑 Lambda 資料處理架構的思想,新增資料根據來源不同分別傳送到不同的通道中去,歷史全量資料通過資料批處理引擎(如 Spark)轉換完成以後批量寫入到資料持久化儲存引擎(TiDB)。增量資料業務應用以訊息的形式傳送到 Kafka 或者 QMQ 訊息佇列,通過本文第三節實時觸發場景中提到的實時資料處理方法,將資料按照標籤持久化的邏輯規則處理完成之後增量寫入到持久化儲存引擎(TiDB),這樣解決資料的時效性問題。
TiDB 有兩大持久化儲存方式,一種是 Row 模式的 TiKV,對於實時線上查詢場景(OLTP)支援的比較好,一種 Column 模式的 TiFlash,對於分析類查詢場景(OLAP)支援的比較好,TiDB 資料儲存內部自動解決這兩個引擎的資料同步問題,客戶端查詢根據自身需要選擇查詢方式。
圖 4-1 Lambda 架構
圖 4-2 CDP 持久化流程
持久標籤的訪問主要場景有兩個,一種是跟現有 CRM 系統對接,線上根據業務的特徵圈選符合條件的業務資料,這種場景的查詢條件不固定,返回結果集因篩選條件而定,對於資料儲存引擎的資料計算和處理能力要求比較高,即我們在資料處理領域經常提到的 OLAP 的場景。另一種場景是線上業務根據前端傳入的業務標籤相關的唯一標識來查詢是否滿足特定業務要求,或者返回指定特徵值,滿足業務處理的需要,需要 ms 級響應,對應的是 OLTP 場景。
五、業務應用
5.1 實時觸發場景應用
在 Trip 的很多業務場景中,需要對多條業務輸入資料做清洗、整合、計算加工處理之後再反饋應用到業務場景中去,促進業務增長。比如 Trip 一些產品線的促回訪、促首單、促復購、優惠券過期、APP 新使用者觸達等 App Push 和 Email 郵件營銷和訊息等場景,提升 Trip 產品曝光和轉化效率。
以 Trip 某產品促回訪 APP Push 推送訊息為例,從頁面的瀏覽行為到觸發傳送的流程可以分為幾個部分:
1)發生瀏覽行為;
2)CDP 實時獲取和處理目標行為日誌資料,傳送給傳送通道;
3)傳送通道完成訊息傳送前處理;
4)根據針對該產品的不同瀏覽行為傳送不同內容的訊息。
根據該產品實時促回訪場景業務需要,以及 CDP 實時觸發場景支援的運算元,配置過濾任務從而動態過濾出該產品促回訪場景需要的資料,根據不同的瀏覽深度打上不同的標籤,推送通道根據深度標籤給不同的客戶端推送不同的內容,具體的 CDP 配置運算元業務邏輯如圖 5-2。
圖 5-2 CDP 某 Trip 產品促回訪觸發邏輯示意圖
通過 CDP 實時觸發場景配置,系統可以根據配置動態生成任務,不需要額外的程式碼開發,並且配置可以動態修改,動態生效,不需要編譯、重啟任務。目前這種方式從執行效果來看時效性更高,更靈活,更穩定,開發測試成本更低,不需要走程式碼開發、編譯、測試、釋出的流程。
5.2 標籤持久化
在第一節中我們提到來自不同業務系統的資料都會有對應的 ID 及標籤與之對應,我們在持久化這些標籤的同時根據業務需要建立這些 ID 之間的 Mapping 關係,如果是一一對映我們會直接儲存 Mapping 關係,如果是多對多的關係我們會根據業務需要,按照首次、最近、全部對映關係等等方式落地 ID Mapping 關係,方便使用者篩選時串聯不同 ID 的特徵。
目前 CDP 已經上線跟攜程國際業務相關的業務系統經過實時清洗、轉換和整合處理後落地的業務特徵標籤庫,系統通過 API 的方式對外提供相關資料查詢和計算服務。目前 CDP 在跟 Trip 各個業務系統深度整合打通,為國際業務增長提供業務特徵標籤庫的資料和服務支援。