微博推薦引擎體系結構簡述
這里有個“道術孰優”的問題,何為“道”?何為“術”?舉個例子的話,《孫子兵法》是道,而《三十六計》則為術。“道”所述,是宏觀的、原理性的、長久不變的基本原理,而“術”則是在遵循基本原理基礎上的具體手段和措施,具有易變性。技術也是如此,算法本省的細節是“術”,算法體現的基本思想則是“道”,知“道”而學“術”,兩者雖不可偏廢,但是若要選擇優先級的話,無疑我會選擇先“道”后“術”——張俊林《這就是搜索引擎》
上一篇文章介紹了推薦產品,給大家有一個初步的認識:微博推薦的目標和使命、推薦產品有哪些以及推薦的分類角度。本文將會給大家描述當前微博推薦的體系結構。
任何不拿出干貨的技術文檔都是耍流氓,首先上體系結構圖,如圖所示,在整體體系結構上,微博推薦可以被劃分為4層:前端展現層、應用層、計算層以及數據層,其中我們把數據日志、統計、監控以及評估也都分在數據層。接下來我會逐一介紹他們的目的,作用、技術與發展。更為細致的描述應該會在以后的博客中體現。
1、推薦前端RFront
RFront主要目的是展現以及渲染微博內容,由于當前微博推薦在web以及客戶端都有相對應的產品,展現差異較大,但數據和方法卻是通用的。那么,需要有這么易于維護、擁抱變化的一層高效地響應產品需求。當然在微博推薦實際業務中,由于產品形態的多樣以及策略的負責性,RFront做了不少工作以及相關的應用技術很多,在接下來的文章中會有相關的同學著重介紹這一塊工作。
2、推薦應用RApp
RApp主要目的是為前端提供候選以及起到部分排序功能。該層利用通用框架【nginx + lua 以及apache + python兩個版本】提供應用接口服務。這些應用包括:內容、用戶、服務、feed推薦頻次以及輔助功能。
在這里有一個工具叫做通用推薦框架(CRF, common recommon framework),它主要的作用是:融合推薦資源、規范推薦應用接口以及統一工作流。早期版本使用的是apache+mod_python的形式,后來在RApp的定位上,認為它是一個數據通路,同時需要獲取各種協議的數據內容,因而將其擴展到nginx + lua的版本。
CRF是一個二次開發框架,無論是早期的apache+mod_python版本還是nginx+lua版本,其核心思想是相似的,它們的目標都是為了較為快速進行推薦策略開發,快速的使用既有推薦存儲數據。主要的體現在:
- 通過透明化不同協議的存儲數據獲取方法,方面獲取推薦資源。比如,獲取mc、redis以及openapi的數據方式是一致的,get以及mget是一個標準的獲取方法。
- 通過建立project的概念,以繼承的方式讓二次開發者建立自己的項目,同時將project中work_core暴露出來,完成主體業務。當然其中也有一個小的技巧,比如global_data以及并行化獲取數據等等。
- 通過暴露出來的common_recom的核心接口來定義推薦的統一接口,我們整理和抽象了所有推薦的接口數據形式,在一定程度上進行了規范和定義,這樣方面了進行接口管理以及對應。比如obj【多用來表示訪問者】,tobj【多用來表示訪問對象】,from【來源】,appkey【分配key】,num【數量】,type【類型,用來區分同一個項目中不同接口】,pid【區分項目】等等。
以下圖是其三層目錄結構【apache+mod_python】:
其中我們通過data_interface來實現數據透明化,通過work_interface來管理項目,my_interface二次開發者開發屬于自己的project。同時需要配置文件【data以及project】進行數據和項目的對應。這樣會帶來一個好處,通過這個框架將所有的資源整合起來了,在推薦早期項目中起到了比較明顯的作用:快速響應算法和產品策略、項目迭代比較迅速同時讓業務人員在一定程度上關注業務,后來也推動了后來推薦存儲架構的誕生。通過不斷的優化,這個逐漸被lua以及c/c++版本的通用框架取代。
3、推薦計算層RCompute
推薦計算層的職責是做高效運算,比如二度關系運算、用戶之間橋梁關系運算、CTR預估等等CPU密集型的功能模塊。同時在RApp以及RFront有一些離線數據采用遠程訪問以前比較低效的,因此我們需要一個更加高效的通用框架來滿足上述要求,lab_common_so孕育而生。
Lab_common_so是基于woo框架的【感謝曾經的同事支持,這是一個輕型的通訊框架,通訊協議以及日志系統比較完善】一個業務流框架,同時兼有了CRF的特點——整合融入數據資源、規范業務流程、統一接口形態,還具有了數據本地化功能。其實在在線demo c/c++開發框架中有很多,在這里主要介紹一些自身特點:
- 通過c++的一些特性,讓二次開發者在工作流上盡可能減少關注其他架構以及通訊包括存儲客戶端的事情,下圖是主要的類結構圖【UML的一套傻傻的不會,大家湊合看吧。】
- 通過global_data以及data的類實現獲取數據的透明化
- 在后期的改造中,將work獨立出來,有開發方自己進行編寫具體實現和具體類,進行so化支持線上更新
在計算層中有一個模塊是RTaining,主要用來進行模型更新以及線上學習的,前期主要用在點擊反饋或者實時模型上。
4、數據RStore
推薦數據對于推薦而言是基礎,決定了性能也決定了效果。因此在數據存儲上花的精力較多。微博推薦存儲的數據擁有以下特點:
- 種類繁雜,比如需要存儲挖掘的靜態數據,還有用戶實時行為的動態數據,有為提升性能而存儲的屬性緩存也有離線運算的直接結果數據
- 存儲選型上也不能一概而論,動態數據以及靜態數據的要求是不一樣,統一都用高效的內存存儲浪費資源,不宜擴展,都用離線的靜態存儲又達不到性能要求
- 多個外部門的數據,溝通和寫作方式各式各樣
- 某些數據量較大,同時在某些數據的實時性要求上較高。
針對上述特點,推薦抽象解決IN/OUT/STORE三部分。下圖詳細的描述了推薦數據的結構圖:
- IN:輸入的關鍵是解決統一和,因此通過建立基于ckestral的統一入口來解決數據規范的事情,同時在日志以及實時數據上也有相應的解決方案,統一入口為RIN。
- OUT:輸出的關鍵是需要透明化,對于業務方而言不需要關系如何進行的服務器分配以及存儲類型,而能夠方面快速穩定地獲取到數據就好。
- STORE:這一塊主要解決數據類型繁雜的工作,推薦的經驗是離線使用lushan以及mapdb,在線使用redis/mc,如果有特殊需求,比如批量高效壓縮存儲特征數據,也會使用一些自己定制的數據存儲形式。
在這里面,需要特別強調的是離線靜態數據存儲,在性能以及成本上找到一定的平衡點是推薦比較有特色的地方,lushan以及mapdb會在之后做專題介紹。同時在推薦發展的過程中,hadoop的引入在一定程度上解決了很多候選以及排序的問題,因此一些map-reduce的結果數據如何放置于線上,推薦系統的r9項目很好的解決了這個問題。
5、數據值輔助工具:日志、監控、評估以及報警
推薦日志系統主要為了解決離線數據分析以及在線監控使用。當前推薦系統針對離線的分析來自于兩塊,一個是來源于自己的日志系統,另外一個是來自于公司的hadoop集群【幾乎涵蓋了非業務方的全局數據】,也在考慮將這兩部分進行整合歸并。
推薦監控系統是去年建設起來的,主要分為三部分:
- 性能監控,主要查看應用、計算以及存儲的性能服務指標,同時與報警體系聯動,及早發現問題、解決問題。目標是實時以及準實時,現在是分鐘級別的。
- 效果監控,主要跟蹤效果的優化和改進,當前重點業務線的效果均在監控系統中
- 對比測試監控,主要針對線上的A/B測試,進行分維度數據展示和對比
以下是我們監控的一些信息:
曝光以及性能監控:
效果監控:
推薦評估系統,當前主要以demo實驗、下線評估以及線上評估三個體系構成,其中線上評估體系主要跟著監控體系來的。而下線以及demo主要是一套前端的展示框架,幾乎涵蓋了推薦所有的接口以及對比測試數據。
推薦報警體系,微博本身是有的,不過由于性能指標以及效果指標存在一定上的定制化需求,這一塊正在花精力解決。
好了,這一篇就到這里,推薦體系結構的介紹基本上告一段落了,其中涉及到的比較細節的工作將會在專題中進行介紹。也請大家多多捧場。
還是老規矩:
Simple is Beautiful! 設計復雜的系統不是難事,難的是用簡單的東西滿足復雜業務,大家共勉!
原文 http://wbrecom.sinaapp.com/?p=48