閱讀325 返回首頁    go 技術社區[雲棲]


基於用戶畫像的實時異步化視頻推薦係統

前言
這個月做的事情還是蠻多的。上線了一個百台規模的ES集群,還設計開發了一套實時推薦係統。 標題有點長,其實是為了突出該推薦係統的三個亮點,一個是實時,一個是基於用戶畫像去做的,一個是異步化。

實時主要體現在三個層麵:
1.用戶畫像中的的短期興趣模型實時構建。

也就是你看完一個視頻,這個視頻幾秒內就影響了你的短期興趣模型,並且反應到你下次的推薦中。


2.候選集實時變更。
在我設計的推薦係統中,候選集的概念是不同類型的待推薦給用戶的視頻庫,一個用戶並不能看到某個候選集的全部,而是能夠看到經過匹配算法處理完後的候選集的一部分。 候選集的更新周期直接影響用戶能夠看到的視頻的實時性。候選集可以有很多,通過不同的候選集解決不同的推薦場景問題。比如結合最新候選集和最近N小時最熱候選集,我們可以做到類似今日頭條的推薦效果。新內容候選集的產生基本就是實時的,而最近N小時熱門視頻候選集則可能是分鍾級別就可以得到更新。還有比如協同就可以做視頻的相關推薦,而熱門候選集則可以從大家都關心的內容裏進一步篩出用戶喜歡的內容。

3.推薦效果指標的實時呈現。
上線後你看到的一些比較關鍵的指標例如點擊轉化率,都可以在分鍾級別得到更新。推薦係統有個比較特殊的地方,就是好不好不是某個人說了算,而是通過一些指標來衡量的。比如點擊轉化率。

用戶畫像和視頻畫像
用戶畫像則體現在興趣模型上。通過構建用戶的長期興趣模型和短期興趣模型可以很好的滿足用戶興趣愛好以及在用戶會話期間的需求。做推薦的方式可以很多,比如協同,比如各種小trick,而基於用戶畫像和視頻畫像,起步難度會較大,但是從長遠角度可以促進團隊對用戶和視頻的了解,並且能夠支撐推薦以外的業務。

異步化
推薦的計算由用戶刷新行為觸發,然後將用戶信息異步發送到Kafka,接著Spark Streaming程序會消費並且將候選集和用戶進行匹配計算,計算結果會發送到Redis 的用戶私有隊列。接口服務隻負責取推薦數據和發送用戶刷新動作。新用戶或者很久沒有過來的用戶,它的私有隊列可能已經過期,這個時候異步會產生問題。前端接口一旦發現這個問題,有兩種解決方案:
  1. 會發送一個特殊的消息(後端接的是Storm集群), 接著hold住,等待異步計算結果
  2. 自己獲取用戶興趣標簽,會按一定的規則分別找協同,然後到ES檢索,填充私有隊列,並迅速給出結果。(我們采用的方案)

除了新用戶,這種情況總體是少數。大部分計算都會被異步計算cover住。


流式技術對推薦係統的影響
我之前寫了很多文章鼓吹流式技術,最露骨的比如 數據天生就是流式的。 當然主要和我這一兩年部門的工作主體是構建
流式流水線(Pipline),解決實時日誌計費等相關問題。流式計算對推薦係統的影響很大,可以完全實現

在推薦係統中,除了接口服務外,其他所有計算相關的,包括但不限於:
  1. 新內容預處理,如標簽化,存儲到多個存儲器
  2. 用戶畫像構建 如短期興趣模型
  3. 新熱數據候選集
  4. 短期協同
  5. 推薦效果評估指標如點擊轉化率
這些流程都是采用Spark Streaming來完成。對於長期協同(一天以上的數據),用戶長期興趣模型等,則是采用Spark 批處理。因為采用了StreamingPro這個項目,可以做到所有計算流程配置化,你看到的就是一堆的描述文件,這些描述文件構成了整個推薦係統的核心計算流程。

這裏還值得提的三點是:
  1. 推薦效果評估,我們采用Spark Streaming + ElasticSearch的方案。也就是Spark Streaming 對上報的曝光點擊數據進行預處理後存儲到ES,然後ES提供查詢接口供BI報表使用。這樣避免預先計算指標導致很多指標實現沒有考慮到而不斷變更流式計算程序。
  2. 複用現有的大數據基礎設施。整個推薦係統隻有對外提供API的服務是需要單獨部署的,其他所有計算都使用Spark跑在Hadoop集群上。
  3. 所有計算周期和計算資源都是可以方便調整的,甚至可以動態調整(Spark Dynamic Resource Allocatioin)。這點非常重要,我完全可以放棄一定的實時性來節省資源或者在閑暇時讓出更多資源給離線任務。當然這些都益於Spark 的支持。
推薦係統的體係結構
整個推薦係統的結構如圖:
c6299e7f47a4b318cbd4b47c53a0038ff7818d56
看起來還是挺簡單的。分布式流計算主要負責了五塊:
  1. 點擊曝光等上報數據處理
  2. 新視頻標簽化
  3. 短期興趣模型計算
  4. 用戶推薦
  5. 候選集計算,如最新,最熱(任意時間段)
存儲采用的有:
  1. Codis (用戶推薦列表)
  2. HBase (用戶畫像和視頻畫像)
  3. Parquet(HDFS) (歸檔數據)
  4. ElasticSearch (HBase的副本)
下麵這張圖則是對流式計算那塊的一個細化:

38b9996d718072ad0aa287c5c845c69349dcb812
用戶上報采用的技術方案:
  1. Nginx
  2. Flume (收集Nginx日誌)
  3. Kafka (接收Flume的上報)

對於第三方內容(全網),我們自己開發了一個采集係統。


個性化推薦示
5af67d321c6e6494e5963b64f511f8ea6ff4db2a
所有候選集都是實時更新的。

這裏我們說下參數配置服務器的概念。

假設我有三個算法A,B,C ,他們分別由三個流式程序完成,各個程序是互相獨立的,最後都會算出各自的結果集。因為不同候選集和算法算出的內容數據量和頻度都會有差異,假設A算出的結果集過大,B算出的結果集很小,但是質量很好,這個時候他們在發送到用戶推薦隊列的時候,需要將自己的情況提交給參數配置服務器,並且由參數服務器決定最後能夠發送到隊列的量。參數服務器也可以控製對應頻度。比如A算法距離上次推薦結果才10s就有新的要推薦了,參數服務器可以拒絕他的內容寫入到用戶推薦隊列。

上麵是一種多算法流程的控製。其實還有一種,就是我希望A,B的結果讓一個新的算法K來決定混合的規則,因為所有算法都是StreamingPro中的一個可配置模塊,這個時候A,B,K 會被放到一個Spark Streaming應用中。K可以周期性調用A,B進行計算,並且混合結果,最後通過參數服配置服務器的授權寫入到用戶推薦隊列。


一些感悟
我14,15年做的一次推薦係統,那個時候還沒有流式計算的理念,而且也不能複用一些已有的技術體係,導致係統過於複雜,產品化也會比較困難。而且推薦的效果也隻能隔日看到,導致效果改良的周期非常長。當時整個開發周期超過了一個多月。然而現在基於StreamingPro,兩三人沒人麼天隻能投入兩三小時,僅僅用了兩個禮拜就開發出來了。後續就是對用戶畫像和視頻畫像的進一步深入探索,核心是構建出標簽體係,然後將這些標簽打到用戶和視頻身上。我們組合了LDA,貝葉斯等多種算法,獲得不少有益的經驗。

最後更新:2017-04-01 17:13:51

  上一篇:go 程序員效率的奧義
  下一篇:go Nginx + Shiro + Ehcache 實現負載均衡集群(成績報告查詢係統)