分享嘉賓:彭克煉 貝殼 資深工程師
編輯整理:馬瑤
出品平臺:DataFunTalk
導讀:隨著貝殼流量的日漸增長,貝殼商業(yè)化細分場景越來越豐富,公司對業(yè)務迭代和效果優(yōu)化的效率有了更高的要求,貝殼商業(yè)化策略算法中臺的架構也在不斷的進行調整和升級。本文將圍繞貝殼商業(yè)化策略算法中臺的架構演進過程,介紹貝殼在商業(yè)化策略算法中臺架構方面的探索和實踐。重點探討貝殼商業(yè)化算法模型落地、架構設計、服務治理以及性能優(yōu)化方面的問題,以及如何增強系統(tǒng)的穩(wěn)定性和擴展性。
01
1. 業(yè)務場景
首先我們看一下業(yè)務場景,用戶通過貝殼找房APP可以找到自己想買的房子,或者想要租的房子,在進入房源詳情頁的時候,房源詳情頁會有一個房源經紀人的展示,這個經紀人在后臺實際上是通過實時競價之后才會出現的,而實時競價是各種經紀人,通過金貝平臺,購買商業(yè)化產品的平臺,去進行小區(qū)的投放,以及進行出價,形成訂單,這個過程會由商業(yè)化這邊會做一個定向推薦,出價建議,以及訂單投放之后的投放診斷,當用戶和經紀人發(fā)生IM對話時,也就是想要咨詢房子的情況,我們就會對貝殼經紀人的貝殼幣進行扣費,所以大家可以看出來,我們和一般互聯網公司不一樣的地方是廣告主是經紀人。
2. 競價排序
接下來我們看一下競價排序的方法,這個和計算廣告類似的,通過eCPM進行經紀人的排序的,eCPM是通過經紀人的出價和CVR的轉化進行預估,兩者相乘得到一個eCPM,這里CVR的話是預估未來7天商機轉委托的概率,相信同學在之前的分享中聽過商機這個詞,用戶和經紀人進行一次對話,我們稱為一個商機,發(fā)生對話后,用戶會把自己的電話委托給經紀人,讓經紀人幫他/她找房子,這個過程我們稱之為委托。所以我們預估就是未來7天商機轉委托的概率。
3. 貝殼的商業(yè)化場景
為了讓大家更好的理解貝殼的商業(yè)化場景,我這里舉例來做一個對比。我們通過門戶網站和貝殼進行對比:
從流量角度來看,門戶網站針對用戶瀏覽頁面,用戶發(fā)生點擊行為稱為流量,而貝殼是用戶點擊IM(商機)稱為是流量。
從用戶定向來看,一般的互聯網公司在做用戶定向的時候,對用戶做各種分析,比如他/她的年齡、性別、地域等,而貝殼主要是針對用戶感興趣的房源進行定向,用戶一般會看某套房子才會咨詢經紀人,所以證明用戶對這套房子是非常感興趣的,用房源來做定向的話,可以說是非常精準的。
從支付方式來看,廣告主就是各區(qū)域的經紀人,支付方式的話,我們用的不是金錢,而是貝殼幣,貝殼幣是我們牽引經紀人完成任務的抓手,平時我們會給經紀人下發(fā)各種任務,經紀人完成任務之后會獲得貝殼幣,有了貝克幣之后就可以購買我們的商業(yè)化產品了,對于經紀人來說,獲得貝殼幣來說就是獲得商機,通過這種方式我們可以牽引經紀人去完成各種任務,更好的服務我們的客戶。
從結算方式來看,很多門戶網站都是通過CPM/CPC的方式進行結算的,而我們是通過CPA方式進行結算,我們對CPA也進行了加強,必須是用戶和經紀人發(fā)生三次有效對話之后才會進行扣費,這樣也是更好的保證經紀人的權益。
4. 商業(yè)化展示
目前我們已經有了眾多的商業(yè)化產品,因為我們最重要的一個展位就是在貝殼APP里面會有很多的曝光,曝光之后就會產生商機,我們重要的兩個商業(yè)化產品:
效果廣告,也稱為商機直通車,其實跟淘寶直通車是非常類似的,也是通過實時競價的方式進行投放,
合約廣告系統(tǒng),目前是有潛課包/小區(qū)吊頂/會員/新房CPS等。
當然了,我們也推出了自然流量,就是通過展位模型的方式給經紀人推薦,比如在首付計算/經紀人列表推薦等等,所以眾多商業(yè)化產品的話,總結一點就是我們是給用戶推薦經紀人的。
2019年,隨著流量增大,對流量進行精細化分類,探索效果廣告。
2020年,我們已經有了眾多的商業(yè)化產品,結算方式也有了CPA/CPM/CPT/CPS等等。
2018年架構產品的業(yè)務形態(tài)
這時的架構是非常粗獷的,對接方主要有兩個,一個是金貝平臺,這是一個商業(yè)化產品購買平臺,
另外一個是adx,這是一個流量分發(fā)的平臺,經紀人在金貝平臺購買了商業(yè)化產品之后,會在CPT上產生訂單數據,通過mysql2hive的方式進入hive表,然后就進行離線分配了。而adx的話,是通過redis數據庫進行一個流量的獲取,經紀人的推薦。
2019年架構產品的業(yè)務形態(tài)
2019年金貝平臺開始售賣效果廣告,所有金貝平臺形成效果廣告的數據,而adx的話,不僅對接到合約廣告,還有實時競價,所以我們起了一套python服務,這項服務因為需要對CVR,也就是剛才提到的eCPM進行預估,因此我們要進行一個模型的訓練,會去收集到日志數據,業(yè)務數據,形成樣本和特征,經過模型訓練,進行在線預估。Python服務的話,我們考慮到開發(fā)效率,所以直接用了python的tornado來進行線上的web服務。
2020年架構產品的業(yè)務形態(tài)
等到2020年的時候,我們的產品就已經非常多了,鉆展CPT,會員,效果廣告,合約廣告等等都接入我們的平臺,ADX不僅接入了效果廣告,合約廣告,也接入了新房CPS,自然展位等眾多的平臺接入進來,還是通過python進行一個在線服務的提供,這時就暴露出幾個問題,一個是python服務出現超時,而且超時越來越嚴重,第二個是hive表在進行離線計算的時候,代碼都是耦合在一起的,第三個是我們在承接新的業(yè)務時,會出現業(yè)務接入費時的情況,我們算法的小伙伴都在進行業(yè)務的接入,而沒有沉下心來對模型進行深入的探究。
2. 過程中的問題與解決方法
第一個是穩(wěn)定性差,性能低,監(jiān)控薄弱的問題。
第二個是數據冗余的問題。
第三個是業(yè)務接入費時的問題,隨著這三個問題越來越嚴重,我們的產品接入方也越來越多,整個過程就形成了惡性循環(huán)。
這時系統(tǒng)重構迫在眉睫,于是,在年初的時候,我們就誕生了一個想法,對整個的系統(tǒng)架構進行重建,出現了商業(yè)化策略算法中臺的架構。
1. 設計過程
既然要設計一個新的架構,肯定要把老的問題都解決掉:
針對性能差的問題,我們拋棄了python的代碼,而是使用java進行服務的構建,python的GIL機制,導致python的多線程是一個偽多線程,而使用python進行多進程,我們知道進程的切換也浪費CPU資源的,所以我們干脆用java來進行服務的重構。
針對穩(wěn)定性差的問題,我們打算引入服務治理的框架,引入服務治理的框架,保證穩(wěn)定性和可擴展性。
針對業(yè)務接入費時問題,我們是對微服務拆分,代碼解耦,服務統(tǒng)一化,形成單一職責,指定責任人。
針對數據孤島問題,我們對離線數據分層,業(yè)務邏輯和公共邏輯進行拆分和重構。針對監(jiān)控薄弱的問題,由于我們引入了服務治理的框架,因此可以對服務過程進行監(jiān)控,模型更新機制監(jiān)控。
2. 架構分層:
解決的以上這些問題之后,我們需要對架構進行分層,分層的好處就是各層次之間相互獨立,通過接口調用。我們是把架構分成了三層:
在線服務層,主要是根據業(yè)務實際場景提供實時、高效、穩(wěn)定的http接口,并靈活的進行AB測試。
近實時層,主要是進行模型訓練、數據存儲、訂閱用戶行為數據等,從而做到秒針級別用戶興趣捕捉和線上效果反饋。
離線計算層,從原始業(yè)務和日志數據進行ETL,形成用戶畫像、經紀人畫像、房源信息、訓練數據等。
3. 各層特點與適合任務的相關規(guī)定
實時層,也就是在線服務層主要使用的是實時+非實時的數據,實時性是秒級,特點是響應速度快,數據實時性敏感,計算復雜度低,穩(wěn)定性高時延低,適合的任務是在線請求。
近實時層使用的數據是實時+非實時,實時性是分鐘級,特點是基于實時數據,計算復雜度適中,隊列可緩沖數據,適合的任務是特征實時計算與更新,實時算法計算(相關性),模型在線更新,指標統(tǒng)計和計算,日志收集和分析。
離線計算層使用的數據是非實時的,實時性是小時級,特點是大數據批量計算,計算復雜度高,大容量存儲,適合的任務是ETL任務(規(guī)則特征樣本),模型的訓練。
4. 各層架構的特點:
我們來看一下整體的架構情況,每個層都會有詳細的模塊與特有的特征。
下面我們將為大家詳細介紹下各層:
1. 在線服務層架構
2. 在線服務層拆分
在線服務層我們要對業(yè)務進行拆分,引入服務治理的框架,不可避免的要對服務進行拆分,拆分主要有兩個原則:
橫向拆分,按照不同的業(yè)務域進行拆分,我們這里是拆分成了效果廣告,合約廣告和自然展位三個業(yè)務域。
縱向拆分,把一個業(yè)務功能里的不同模塊或者組件進行拆分,從多個業(yè)務角度找共性,將服務進行抽離,確定各個服務邊界,清晰職責。
這里我們看一個例子,這是兩個主要的業(yè)務。一個是不走商業(yè)化流量的自然展位經紀人推薦,另外一個是商業(yè)化經紀人推薦。
自然展位經紀人推薦是要經過一個召回模塊,規(guī)則過濾,特征處理,排序模型,兜底規(guī)則。商業(yè)化經紀人推薦是不走召回模塊,因為它的業(yè)務主要是從前端傳過來的,就是這個經紀人有訂單了,就會直接召回,因為整個過程越激烈,對我們來說是越有好處的,召回完成之后,會進行預算控制,這是比較特殊的一點,后面會講,其實就是對經紀人做一層過濾,然后進行特征處理,排序模型,融合規(guī)則,融合的話,會計算eCPM。
這兩個過程有很多相似的地方,所以我們對這兩個過程其中的一些部分進行了抽離,比如說規(guī)則過濾和預算控制過濾,我們抽離成過濾模塊,特征處理我們抽離成了特征處理模塊,排序模型我們抽離成了模型模塊,兜底規(guī)則和融合規(guī)則我們抽離成了融合層的服務。
在線服務層拆分原則:
我們來看一下在線服務層拆分前和拆分后的狀態(tài)。中控主服務主要包括策略配置,召回階段,特征處理,排序階段,融合階段。
在線服務層拆分形態(tài)和調用流程:
我們來詳細看一下在線服務層的各個部分。請求會通過統(tǒng)一網關進入中控主服務,中控主服務會調用下面的各個子服務,比如召回,過濾,特征處理,排序,融合。召回里面有很多召回的方式,過濾里面也會有很多過濾的方式。接下來我會介紹一下每個服務里面設計的特點。
3.中控主服務,主要功能:
配置讀取,我們會對每個要調用的服務進行配置化,有些業(yè)務需要一種召回方式,有些業(yè)務需要多種方式進行召回,我們都可以通過配置的方式進行更新。
讀取配置后,需要對微服務進行依次調度,形成調用工作流。
會對熔斷降解方案的設定。
4. 策略配置設計的過程
左邊是一張mysql的表,我們可以看到這里的字段有召回策略,過濾策略,排序策略,融合策略等,針對每個策略,我們都可以設定召回策略的參數,排序策略的參數等等。舉個例子比如這里有個展位,我們可以設定它的召回策略,過濾策略,排序策略以及融合策略。
5. 中控主服務的特點:
對外提供HTTP服務,對內微服務調用使用RPC或者HTTP。
各微服務調用時間使用動態(tài)設置,一般各模塊實際超時時間=Min(該模塊最大超時時間,剩余時間)。
盡量不包含業(yè)務邏輯,減少迭代。
6. 在線服務層中召回模塊
第一個我們會做KV召回—主要是業(yè)務規(guī)則的召回。把計算好的數據放在KV數據庫里面,比如用戶來了之后,點了某一套房子,然后我們通過房源召回錄入人,維護人,有過帶看的人,有過交易的人,這樣就可以把經紀人召回來,如果這個小區(qū)沒有數據的話,就再往上一層,分別來做兜底,小區(qū)沒有的話就從商圈的維度去召回經紀人。還有一種就是從經紀人id進行召回,這個主要是金貝平臺,我們需要給經紀人推薦他/她感興趣的小區(qū),她/他(經紀人)肯定會選擇看有過帶看的房源,有過交易的房源。
ES召回
ES召回有一些復雜的召回,比如用戶id,年齡,性別,各種條件的查詢條件適用于冷啟動的問題。ES集群還有一些用戶特征,經紀人特征,是從DMP平臺獲取的。ES的好處是實時性更高,集群操作,可以做簡單計算和排序。ES里面也支持向量召回,效果也不錯,我們有一些場景用到了ES的向量召回。
向量召回
這個在深度學習向量檢索的需求非常大,我們之前使用的Facebook開源的一個工具faiss. 將數據源離線計算后,向量數據定時更新,通過一個接口索引部分,將結果向量送入faiss. 另外一個接口是通過faiss, 把向量集合送入到搜索部分。
但是faiss有一個缺點它是單機部署,沒有分布式,所以我們使用了另外一個比較火的向量召回的框架叫Milvus,上面這個是我從官網上截的一張圖,它的底層架構也是基于faiss的,它是使用了負載均衡,服務發(fā)現,對底層的數據進行分片,來保證穩(wěn)定性和高性能。
embedding向量生成的原理
這里我們有多種模型生成embedding,主要是通過node2vec。也就是說用戶在瀏覽APP的時候,會生成很多的房源序列,根據房源序列我們可以抽象出一張圖,這跟我們使用的word2vec是非常類似的,生成一張圖之后,會做隨機游走,之后將結果輸入到word2vec,生成embedding的向量。
7. 如何去做線上的serving
線上serving目前沒有比較好的開源的解決方案,公司都會有一套線上自己的serving服務。而我們主要有兩種方式,一種是PMML格式的文件進行線上serving, 這個主要用在一些比較簡單的模型,比如樹模型、線性模型進行多線程的調用,這里主要是用spark平臺,python平臺,我們可以通過模型訓練之后,使用JPMML插件,形成PMML模型文件,然后把這種文件放在數據庫或文件系統(tǒng)中,最后可以通過java服務進行線上推斷。
另外一種在線服務的方式,tfserving---貝殼模型serving平臺run once。上面是一個架構圖。支持比如說Tensorflow, Pytorch等一些在線serving。
過濾服務
預算控制,經紀人會在金貝平臺生成訂單,然后他/她會先把錢充到賬戶里面,那么我們肯定需要平穩(wěn)的對經紀人的預算進行消耗。
頻率控制,我們不想讓用戶看到同樣的廣告次數太多,我們會對這些廣告進行過濾,但是我們這里會對廣告主進行頻率控制,也就是經紀人作業(yè)經歷有限,如果我們一次給他/她的商機也就是用戶太多的話,她/他會處理不過來,所以我們會對經紀人的頻率進行控制。
業(yè)務方規(guī)則,可以通過RPC的方式調用業(yè)務方的接口進行過濾。
微服務的技術選型
業(yè)務方會通過SpringCloud Gateway進入到服務里面,公司的服務會統(tǒng)一到Eureka 平臺進行注冊,每個微服務是通過Feign進行通信,通過Ribbon進行服務的負載均衡,中間也用到很多開源的組件,比如接口鑒權(OpenAM),異常診斷(hawk),鏈路追蹤(KeTrace),熔斷限流(Sentinal),配置(Appolo),服務診斷(arthas),監(jiān)控Prometheus+grafana界面來實時監(jiān)控。
1. 近實時層架構圖
2. 近實時層數據收集
近實時層大多數公司的架構可能差不多。我們這里主要是會存儲各種各樣的數據,比如mysql數據,redis數據,向量數據,另外一個就是會對實時數據進行收集,比如用戶訪問貝殼網站,鏈家網站,貝殼App之后,會留下數據,后臺會進行埋點,然后通過kafka進入實時計算的模塊,最后會計算出一些規(guī)則的數據,記錄到mysql,redis,進行一些向量的計算,進入milvus,進行向量搜索,我們也會把數據進入到ES里面做一些報表,還有做一些ELK的分析,以及HDFS的備份。
1. 離線層架構圖
2.離線層分層:
離線層在這個框架里面是一些功能,但是我們也對離線層進行了分層:基礎數據層、特征工程層、基礎數據層。
基礎數據層,我們會從DMP平臺獲取到用戶的畫像,經紀人畫像和業(yè)務數據(樣本,曝光,商機等),在這之上會生成客源特征,經紀人特征,房-人特征,我們這里主要是給用戶推薦經紀人,所以在使用的過程中我們發(fā)現使用房的特征做推薦對房的成交量作用并不大,我們就弱化了房的特征,關注經紀人特征和人的特征,因為我們發(fā)現用戶在看這套房子,和最后成交的房子關系并不大,而經紀人和用戶建立聯系之后,經紀人會給用戶推薦各種各樣的房子,最后成交的并不一定是這個用戶看的,再上面一層是模型層,包括模型訓練,離線效果評估,以及模型更新。
3. 離線訓練部分
這是離線訓練的部分。主要是使用特征進行離線模型訓練,我們用到了LR,Li ghtGBM, WideDeep, DeepFM等等。
4. 架構重構之后的效果:
穩(wěn)定性,由97%升高到99.99%。
性能提升—滿足同樣QPS情況下,機器由原來的36個8核12g實例減少到24個4核6g實例。成本上有了大的減少。
人效方面的提升,可以通過hawk隨時查看訪問數據,異常實時報警,通過IM告知給具體的責任人,通過界面化方式配置微服務的熔斷降級方案。
這里是我們通過界面的方式配置熔斷限流策略,微服務的熔斷策略,之前要修改這些配置需要改代碼,現在需要界面就可以了。
當有新的接入方,我們可以打開城市、策略配置,做AB實驗/各模塊策略的配置,也可以對業(yè)務進行召回,過濾,排序等一些策略的設定,策略靈活設置,分鐘級上線、生效。
這是一個效果的指標看板??梢钥吹紺PA轉化情況,商機的情況,轉委托的情況,也能看到AB實驗的結果,就是具體每個策略的轉化結果是什么樣的,這里也能看到詳細的情況。
主要有四個方面:
貝殼商業(yè)化平臺計劃要打造AI算法中臺,容納更多業(yè)務。不局限于商業(yè)化的業(yè)務,還會有圖像,估價之類的。
兼容多語言。之前有些系統(tǒng)可能是python, go語言,我們都可以去對接他們的業(yè)務。
服務性能優(yōu)化,使用性能更高的RPC框架,進一步提升內部性能。
探索更多模型。比如在深度學習方面更多的模型以及線上的部署。
今天的分享就到這里,謝謝大家。
特別推薦一個分享架構+算法的優(yōu)質內容,還沒關注的小伙伴,可以長按關注一下:
長按訂閱更多精彩▼
如有收獲,點個在看,誠摯感謝
免責聲明:本文內容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯系我們,謝謝!