Apache Flink 在實時金融數據湖的應用 一、背景 二、京東搜索在線學習架構 三、實時樣本生成 四、Flink Online Learning 五、監控系統 六、規劃總結

本文由京東搜索算法架構團隊分享,主要介紹 Apache Flink 在京東商品搜索排序在線學習中的應用實踐。文章的主要大綱如下:

1、背景
2、京東搜索在線學習架構
3、實時樣本生成
4、Flink Online Learning
5、監控系統
6、規劃總結

一、背景

在京東的商品搜索排序中,經常會遇到搜索結果多樣性不足導致系統非最優解的問題。爲了解決數據馬太效應帶來的模型商品排序多樣性的不足,我們利用基於二項式湯普森採樣建模,但是該算法仍存在對所有用戶採用一致的策略,未有效考慮用戶和商品的個性化信息。基於該現狀,我們採取在線學習,使深度學習和湯普森採樣融合,實現個性化多樣性排序方案,實時更新模型的關參數。

在該方案中,Flink 主要應用於實時樣本的生成和 online learning 的實現。在在線學習過程中,樣本是模型訓練的基石,在超大規模樣本數據的處理上,我們對比了 Flink、Storm 和 Spark Streaming 之後,最終選擇用 Flink 作爲實時樣本流數據的生產以及迭代 online learning 參數的框架。在線學習的整體鏈路特別長,涉及在線端特徵日誌、流式特徵處理、流式特徵與用戶行爲標籤關聯、異常樣本處理、模型動態參數實時訓練與更新等環節,online learning 對樣本處理和參數狀態處理的準確性和穩定性要求較高,任何一個階段都有可能出現問題,爲此我們接入京東的 observer 體系,擁有完整的全鏈路監控系統,保證各個階段數據的穩定性和完整性;下面我們首先介紹一下京東搜索在線學習架構。

二、京東搜索在線學習架構

京東搜索的排序模型系統架構主要包括以下幾個部分:

1、Predictor 是模型預估服務,在 load 模型中分爲 static 部分和 dynamic 部分,static 部分由離線數據訓練得到,主要學習 user 和 doc 的稠密特徵表示,dynamic 部分主要包含 doc 粒度的權重向量,這部分由實時的 online learning 任務實時更新。
2、Rank 主要包括一些排序策略,在排序最終結果確定之後,會實時落特徵日誌,將 doc 的特徵按順序寫入特徵數據流,作爲後續實時樣本的數據源(feature)。
3、Feature Collector 的任務是承接在線預估系統發出的特徵數據,對下游屏蔽緩存、去重、篩選等在線系統特有邏輯,產出 Query+Doc 粒度的特徵流。
4、Sample join 的任務將上面的 feature 數據、曝光、點擊、加購、下單等用戶行爲標籤數據作爲數據源,通過 Flink 的 union + timer 數據模型關聯成爲符合業務要求的樣本數據,算法可根據目標需求選擇不同的標籤作爲正負樣本標記。
5、**Online learning **任務負責消費上游生成的實時樣本做訓練,負責更新 model 的 dynamic 部分。

三、實時樣本生成

Online Learning 對於在線樣本生成的時效性和準確性都有很高的要求,同時也對作業的穩定性有很高的要求。在海量用戶日誌數據實時湧入的情況下,我們不僅要保證作業的數據延時低、樣本關聯率高且任務穩定,而且作業的吞吐不受影響、資源使用率達到最高。

京東搜索排序在線樣本的主要流程如下:

1、數據源大致有曝光流、feature 流和用戶行爲流等作爲實時樣本的數據源,統一以 JDQ 管道流的形式,由京東實時計算平臺提供平臺支撐。
2、接到 feature 流和曝光流、label 流後,進行數據清洗,得到任務需要的數據格式。
3、拿到各個標準流後,對各個流進行 union 操作,之後進行 keyby。
4、我們在 process function 裏面添加 Flink timer 定時器,作爲樣本生成的實時窗口。
5、將生成的樣本實時落入 jdq 和 HDFS,jdq 可以用作後面的 online learning 的 input,HDFS 持久存儲樣本數據,用於離線訓練、增量學習和數據分析。

在線樣本任務優化實踐:

京東搜索樣本數據吞吐量每秒達到 GB 規模,對分佈式處理分片、超大狀態和異常處理提出很高的優化要求。

1、數據傾斜

使用 keyby 的時候,難免會有數據傾斜的情況,這裏我們假設 key 設計合理、 shuffle 方式選擇正確、任務沒有反壓且資源足夠使用,由於任務 parallelism 設置導致的數據傾斜的情況。我們先看 Flink 裏面 key 是如何被分發到 subtask 上面的。

keygroup = assignToKeyGroup(key, maxParallelism)
subtaskNum = computeOperatorIndexForKeyGroup(maxParallelism, parallelism, keyGroupId)

假設我們的併發設置的是 300,那麼 maxParallelism 就是 512,如此設計,必然導致有的 subtask 分佈 1 個 keygroup 有的分配兩個,同時也導致了數據自然傾斜。針對上述問題,有兩個解決方案:

  • 設置並行度爲 2 的 n 次方;
  • 設置最大並行度爲 並行度的 n 倍。

如果使用方案 1 ,調整併發的話只能調整 2 的冪次,建議使用方案 2,且假如 parallelism 爲 300,maxParallelism 設置爲 1200 的情況下假如數據還是有傾斜,可以再相應的把 maxParallelism 設置大一些保證每個 keygroup 的 key 少一些,如此也可以降低數據傾斜的發生。

2、large checkpoint

在線樣本用到了 Flink 的 state,我們之前默認將 state 放到了內存裏面,但是隨着放量的增加,state 數據量激增,發現 GC 時間特別長,之後改變策略,將 state 放入了 RocksDB,GC 問題得以解決。我們針對 checkpoint 做了如下配置:

  • 開啓增量 checkpoint;
  • 合理設置 checkpoint 的超時時間、間隔時間和最小暫停時間。
  • 讓 Flink 自己管理 RocksDB 佔用的內存,對 RocksDB 的 blockcache、writebuffer 等進行調優。
  • 優化 state 的數據使用,將 state 數據放入多個 state object 裏面使用,降低序列化/反序列化的代價。

在任務調優的時候我們發現我們的任務訪問 RocksDB 的時間非常長,查看 jstack 發現,很多線程都在等待數據的序列化和反序列化,隨着算法特徵的逐漸增多,樣本中的特徵個數超過 500 個,使得每條數據的量級越來越大。但是在做樣本關聯的時候其實是不需要特徵關聯的,只需要相應的主鍵關聯就可以了,因此,我們用 ValueState 存儲主鍵,用 MapState/ListState 存儲特徵等值。當然了還可以將這些特徵值存儲到外部存儲裏面,這裏就需要對網絡 io 和 本地 io 之間的選擇做一個取捨。

  • failure recovery 的時候開啓本地恢復。

由於我們的 checkpoint 數據達到了 TB 級別,一旦任務發生 failover,不管是針對 HDFS 還是針對任務本身,壓力都非常大,因此,我們優先使用本地進行 recovery,這樣,不僅可以降低 HDFS 的壓力還可以增加 recovery 的速度。

四、Flink Online Learning

對於 online learning,我們先介紹一下伯努利湯普森採樣算法,假設每個商品的 reward 概率服從 Beta 分佈,因此給每個商品維護兩個參數成功次數 si 及失敗次數 fi,及所有商品的公共先驗參數成功次數 α 和失敗次數 β。

每次根據商品相應的 Beta 分佈採樣爲最優商品的期望 reward: Q(at) = θi,並選擇期望 reward 最大的商品展現給用戶。最後根據環境給出真實 reward,更新模型相應的參數達到 online learning 的效果。該參數代表一個商品特徵,用一個 n 維向量表示,該向量由原始特徵通過 MLP 網絡預測得到。原始特徵經過 DNN 網絡得到一個 N 維向量作爲該商品的個性化表徵,採用 Logistic Regression 函數建模似然函數,利用 Flink 構建該表徵和實時反饋所組成的實時樣本,用於不斷迭代近似更新參數分佈。

1、數據有序性保證

從 jdq 接過實時樣本之後,由於之前並沒有保證數據的有序性,這裏採用 watermark 機制保證數據的有序性。

2、樣本數據處理

把只曝光無行爲的商品看做負樣本,有點擊及後續行爲的商品看做正樣本,當窗口將達到一定正負比例或數據量時進行一次 batch 訓練,迭代出新的參數向量,將商品 embedding 數據放到 Flink 的 state 裏面,之後作爲 model 的 dynamic 部分更新參數。

3、 同步迭代、異步迭代

個性化 ee 參數在線學習採用異步更新方式的時候,存在參數更新順序錯亂問題,這會降低在線學習模型收斂速度,從而造成了流量的浪費,因此,參數異步更新方式更改爲同步更新方式,避免參數讀寫錯亂問題。在同步更新的方式下,存儲在 status 中的參數向量需要在下一次訓練迭代時使用,若參數發生丟失會使該商品的迭代過程中斷,爲防止系統風險造成參數丟失,設計了參數雙重保障。一般的任務異常或重啓後參數可從 checkpoint 或 savepoint 中恢復,如果意外情況下參數無法恢復,從遠程在線服務中取回上一版參數並記錄到 state。

4、多試驗版本支持

在線學習任務使用同一個 Flink 任務來支持多個版本模型在不同實驗桶下進行 AB 實驗,通過版本號區分不同的 AB 流量桶,對應的實時樣本以 docid+version 作爲 key 進行處理,迭代過程互不影響。

5、custom serialization

爲了提高帶寬利用率以及性能的需求,我們內部採用 pb 格式傳輸數據,經過調研,pb 的傳輸格式優於 Flink 的兜底的 general class 的 kryo 序列化方式,因此我們採用了 Flink 的 custom serialization 解決方案,直接用 pb 格式在 op 之間傳輸數據。

五、監控系統

這裏我們區分業務全鏈路監控和任務穩定性相關監控,具體情況下面將詳細介紹。

1、全鏈路監控

整個系統使用京東內部的 observer 平臺來實現業務全鏈路監控,主要包括 predictor 服務相關的監控、feature dump 的 QPS 監控、特徵和標籤質量監控、關聯情況監控、train 相關的監控以及 AB 指標相關的一些監控,如下:

2、任務穩定性監控

任務穩定性監控這裏主要是指 Flink 的任務穩定性監控,鏈路吞吐量達 GB/s規模,特徵消息 QPS 達 10W 規模,且 online learning 的不可間斷性,不管對於在線樣本任務還是 online learning 的任務,相關監控報警都是必不可少的。

  • 容器的內存、cpu 監控、thread 個數,gc 監控
  • 樣本相關業務監控

六、規劃總結

Flink 在實時數據處理方面有優秀的性能、容災、吞吐等表現、算子豐富易上手使用、自然支持批流一體化,且目前已有在線學習的框架開源,做在線學習是個不二的選擇,隨着機器學習數據規模的擴大和對數據時效性、模型時效性要求的提升,在線學習不僅僅作爲離線模型訓練的補充,更成爲模型系統效率發展的趨勢。爲此我們做的規劃如下:

原文鏈接

本文爲阿里雲原創內容,未經允許不得轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章