0到1再到100 蘑菇街搜索與推薦架構(gòu)的探索之路
原創(chuàng)【51CTO.com原創(chuàng)稿件】丁小明,花名小寶,蘑菇街搜索技術(shù)團(tuán)隊(duì)負(fù)責(zé)人。2011年底加入蘑菇街,2013年開始負(fù)責(zé)搜索團(tuán)隊(duì),見證了蘑菇街一路蓬勃發(fā)展的歷程,也和團(tuán)隊(duì)一起從零起步摸爬滾打,打造了蘑菇街的搜索推薦體系,包括自主研發(fā)的C++主搜引擎和廣告引擎、實(shí)時(shí)個(gè)性化推薦系統(tǒng)、基于開源Solr/ES深度定制的實(shí)時(shí)搜索平臺(tái)等。
小寶·蘑菇街搜索技術(shù)團(tuán)隊(duì)負(fù)責(zé)人
以下內(nèi)容根據(jù)小寶老師在WOTA2017 “電商大促背后的技術(shù)挑戰(zhàn)”專場(chǎng)的演講內(nèi)容整理。
我將和大家分享蘑菇街在搜索推薦上踩過的坑及在探索路上的經(jīng)驗(yàn)總結(jié)。我們的經(jīng)驗(yàn)雖算不上業(yè)界最佳實(shí)踐,但也是一步步從0到1再到100,希望大家可以從中得到一些收獲。
搜索架構(gòu)的探索之當(dāng)前現(xiàn)狀
蘑菇街搜索當(dāng)前架構(gòu)
如上圖,是蘑菇街當(dāng)前搜索架構(gòu),分為在線和離線兩部分。在線部分主要職責(zé)是處理在線的搜索請(qǐng)求。離線部分的主要職責(zé)是處理數(shù)據(jù)流。
在線請(qǐng)求鏈路
如上圖,是整個(gè)在線請(qǐng)求鏈路,主要分為topn->qr->引擎->精排->透出五個(gè)環(huán)節(jié)。
第一步,請(qǐng)求首先進(jìn)入topn系統(tǒng),做ab配置/業(yè)務(wù)請(qǐng)求鏈路配置。
第二步,請(qǐng)求進(jìn)入QR改寫系統(tǒng)做切詞,同義詞擴(kuò)展,類目相關(guān)性,插件化等。
第三步,進(jìn)入U(xiǎn)PS用戶個(gè)性化數(shù)據(jù)存儲(chǔ)系統(tǒng)。
第四步,投放層得到UPS和QR兩部分的數(shù)據(jù)后,放入搜索引擎做召回。搜索主要會(huì)經(jīng)過一輪海選,海選的依據(jù)是文本相關(guān)性和商品質(zhì)量,這樣做是為確保召回的商品質(zhì)量大致可靠。之后會(huì)經(jīng)過多輪初選,過程中會(huì)應(yīng)用到更復(fù)雜的算法模型,對(duì)海選的結(jié)果進(jìn)行排序。搜索引擎得到粗排的結(jié)果約千級(jí)別。
第五步,粗排結(jié)果進(jìn)入到精排系統(tǒng),精排系統(tǒng)主要通過算法,做個(gè)性化排序、實(shí)時(shí)預(yù)測(cè),精排和引擎類似,也支持多輪排序。經(jīng)過精排系統(tǒng)之后,最終把結(jié)果透出給業(yè)務(wù)層。
蘑菇街統(tǒng)一引擎系統(tǒng)
如上圖,左側(cè)紅色框內(nèi)是蘑菇街統(tǒng)一引擎系統(tǒng),包含用戶個(gè)性化存儲(chǔ)系統(tǒng)、精排存儲(chǔ)、商品引擎、廣告引擎等。由于這樣的形式維護(hù)成本特別高,故做了右圖這個(gè)統(tǒng)一的Zindex內(nèi)核架構(gòu)。這個(gè)架構(gòu)的最底層是共享內(nèi)存分配器,再上層是可支持不同數(shù)據(jù)結(jié)構(gòu)的各種引擎,再上層是索引管理。基于這個(gè)架構(gòu),不同的引擎可根據(jù)各自需求去創(chuàng)建自己的索引。
跟這個(gè)架構(gòu)相關(guān)的,就是我們的運(yùn)維平臺(tái),是基于公司Docker虛擬化技術(shù)做的一個(gè)運(yùn)維平臺(tái),能夠非常快的支持索引創(chuàng)建,包括創(chuàng)建之后整個(gè)索引數(shù)據(jù)的管理。還有就是排序平臺(tái),用來提供算法配置變更服務(wù)。
搜索架構(gòu)離線部分的數(shù)據(jù)流程
如上圖,是離線的數(shù)據(jù)流程的情況,主要職責(zé)是數(shù)據(jù)流的處理,完整的索引數(shù)據(jù)分為算法數(shù)據(jù)和業(yè)務(wù)數(shù)據(jù)。
算法數(shù)據(jù)參與排序,整個(gè)鏈路從最前端ACM打點(diǎn)、再落到整個(gè)數(shù)據(jù)倉庫、經(jīng)過清洗之后,在數(shù)據(jù)平臺(tái)上跑訓(xùn)練腳本,得出的特征導(dǎo)到特征平臺(tái),再同步到線上。
業(yè)務(wù)數(shù)據(jù)的主要來源就是DB,DB中主要存儲(chǔ)商品、店鋪之間的數(shù)據(jù),業(yè)務(wù)變更主要基于mysql bin-log事件監(jiān)聽,變更之后做全量和增量。全量每天定時(shí)索引操作、增量會(huì)流到MQ,再通過業(yè)務(wù)拼裝推到線上。
搜索架構(gòu)的探索之演變歷程
蘑菇街搜索架構(gòu)主要經(jīng)歷導(dǎo)購時(shí)期(~2013.11)、電商初期(2013.11~2014.11)、Solr主搜(2015.4~2016.3)、C++主搜(2015.8~2016.11)、平臺(tái)化(2017.1~now)五大階段。
蘑菇街搜索架構(gòu)現(xiàn)狀簡化版
為了更清晰直觀進(jìn)行對(duì)比,我把當(dāng)前搜索架構(gòu)簡化成如上圖所示的業(yè)務(wù)、投放、排序、召回、數(shù)據(jù)流五大層。接下來我們來看看,我們從最早期,都經(jīng)歷哪些演變,一步步走到現(xiàn)在。
蘑菇街搜索架構(gòu)導(dǎo)購時(shí)期架構(gòu)
如上圖,是~2013.11導(dǎo)購時(shí)期的架構(gòu),有用到放在PHP代碼里的業(yè)務(wù)+投放、用Java搜索引擎Solr做的召回+排序和數(shù)據(jù)流三層。這個(gè)時(shí)期,排序需求不是很迫切,更多側(cè)重的是商品整體的豐富度和新穎度。簡單理解,熱銷排序等于喜歡乘10加上收藏乘50,基于Solr的改造來實(shí)現(xiàn)。
在電商轉(zhuǎn)型初期(2013.11~2014.11),由于賣自己的商品,流量變得更值錢了,工程師會(huì)想法設(shè)法去提升流量的效率。同時(shí)用戶行為也在增加,產(chǎn)生更多的數(shù)據(jù)。還有增量管理復(fù)雜,數(shù)據(jù)量大、Optimaize風(fēng)險(xiǎn)大、導(dǎo)購、廣告和搭配等多類型商品透出等等。其中最明顯挑戰(zhàn)就是排序特征變多、數(shù)據(jù)變大、次數(shù)頻繁。
蘑菇街搜索架構(gòu)轉(zhuǎn)型初期架構(gòu)
面對(duì)這些挑戰(zhàn),當(dāng)時(shí)的思路是把算法獨(dú)立成單獨(dú)Java工程做算分,但百萬商品百種排序,算法排序達(dá)G級(jí)別,這些排序數(shù)據(jù)需要作用于搜索引擎,快速生效,問題是用增量的方式會(huì)引來索引碎片的增加,會(huì)給線上引擎穩(wěn)定性帶來波動(dòng)。故另辟蹊徑,用在Solr進(jìn)程中設(shè)置堆外內(nèi)存來管理這部分排序數(shù)據(jù)。
總結(jié)來說,轉(zhuǎn)型初期整體的解決方案就是把算法獨(dú)立出來單獨(dú)去做,把部分分?jǐn)?shù)盡快同步到引擎,進(jìn)行生效。這樣的方法,當(dāng)時(shí)線上效果很顯著,但隨時(shí)間推移又有新問題出來:
- 規(guī)則排毒->LTR,算法排序需求多;
- 排序靈活性制約:計(jì)算好的分?jǐn)?shù)離線推送到Solr;
- Solr內(nèi)存壓力:GC/段合并;
- 靜態(tài)分,相關(guān)性差;
- 大促相關(guān)性問題:搜索“雨傘”,雨傘圖案的連衣裙會(huì)排在前面;
Solr主搜整體架構(gòu)
針對(duì)這些新問題,(2015.4)Solr主搜改造,支持Rank插件(Ranker->Scorer),配置化+動(dòng)態(tài)化,整體架構(gòu)如上圖。應(yīng)對(duì)相關(guān)性問題,新增QR系統(tǒng)、應(yīng)對(duì)內(nèi)存壓力,做Solr升級(jí)(Docvalues),算法分走動(dòng)態(tài)字段增量,同時(shí)投放方式也漸漸形成Topn系統(tǒng),對(duì)外對(duì)接不同的搜索場(chǎng)景。
Solr架構(gòu)解決相關(guān)性、算法變更線上排序等問題,但新問題在于雖用機(jī)器學(xué)習(xí)的排序做法,但那個(gè)時(shí)期主要是爆款模型,有很多個(gè)性化需求模型同時(shí)對(duì)不同人要有不同的排序結(jié)果,還有一些重排序或打散等更加復(fù)雜的需求。因Solr實(shí)現(xiàn)機(jī)制的限制,只能做一輪排序,想要改動(dòng)比較難。另外,Solr整個(gè)索引結(jié)構(gòu)非常復(fù)雜,二次開發(fā)成本高,內(nèi)存、性能上也慢慢地暴露出很多問題,同時(shí)還有Java的GC也是不可逾越的鴻溝。
當(dāng)時(shí)多輪排序的需求,除了做一些文本相關(guān)性,還相對(duì)商品做品牌加權(quán),如想扶持某些品牌、做類目打散等,這些在單輪排序內(nèi)做不到,原來的方式只能把多輪融合在一個(gè)排序中搞定,但效果會(huì)很差。
C++主搜架構(gòu)
如上圖,是C++主搜架構(gòu)(2015.8~2016.11)上線,在整個(gè)性能和排序方面做了定制,可支持多輪排序、整個(gè)內(nèi)存采用內(nèi)存方式,由排序體系支撐。這個(gè)階段整體來看,相對(duì)是完善的,每層,整個(gè)系統(tǒng)都成型,可數(shù)據(jù)流環(huán)節(jié)又出現(xiàn)了三個(gè)問題:
- 全量無調(diào)度,都要依靠流程制約
- 增量帶來算法分?jǐn)?shù)不可比,會(huì)帶來一些線上排序的抖動(dòng)
- 業(yè)務(wù)數(shù)據(jù)增量對(duì)服務(wù)接口壓力過大(促銷故障)
全量的整個(gè)鏈路
如上圖,是全量的整個(gè)鏈路,算法序列的整個(gè)鏈路靠時(shí)間約定,數(shù)據(jù)容災(zāi)機(jī)制弱。所以大促時(shí),前置任務(wù)延遲全量做不了,線上內(nèi)存幾乎撐爆,經(jīng)常性全量延時(shí),必須手動(dòng)去處理。還有算法誤導(dǎo)排序分,導(dǎo)致線上錯(cuò)亂,增量恢復(fù)時(shí)間長。
要解決這個(gè)問題,我們首要引入一個(gè)基于Zookeeper的調(diào)度系統(tǒng),把整個(gè)數(shù)據(jù)流驅(qū)動(dòng)起來同時(shí)支持錯(cuò)誤報(bào)警。容災(zāi)部分的思路就是增加排序SOS字段、基于HBase定期生成全量快照,快速回檔、單算法字段修復(fù)等。
兩次算法增量分?jǐn)?shù)不可比,增量生效特別慢。如時(shí)刻1算出商品是90分,時(shí)刻2是60分,就會(huì)引起線上排序抖動(dòng),主要因算法兩次序列導(dǎo)致整個(gè)數(shù)據(jù)分布不同,特別到大促時(shí)期,不同時(shí)段成交數(shù)據(jù)變化特別快,商品排序的波動(dòng)非常明顯,增量數(shù)據(jù)同一批正常,但兩次見就會(huì)出錯(cuò)。當(dāng)0點(diǎn)大家在瘋狂購物的時(shí)候,變更非常頻繁,會(huì)導(dǎo)致排序錯(cuò)亂。算法數(shù)據(jù)出錯(cuò)后,生效時(shí)間也會(huì)比較慢。
如上圖,我們的解決方案是通過小全量的方式把算法、分?jǐn)?shù)單獨(dú)拖到線上引擎本地,在引擎本地依次一次加載,直接切換的方式,讓每一次算法增量數(shù)據(jù)的數(shù)據(jù)加速生效,容災(zāi)也會(huì)加快。
如上圖,由于變更都是Doc級(jí)更新,每一個(gè)字段更新都會(huì)調(diào)用所有的接口去拼裝成一條完整的數(shù)據(jù)去更新,這導(dǎo)致業(yè)務(wù)增量壓力特別大。大促期間,增量QPS可以達(dá)到幾千~上萬,對(duì)下游40多個(gè)接口的壓力非常大。
如上圖,這個(gè)問題解決的思路是讓引擎,包括數(shù)據(jù)流支持字段更新。只拼裝變更字段、不需要拼裝完整的數(shù)據(jù),這需要引擎本身支持才能做到。當(dāng)時(shí)上線,收益非常明顯,關(guān)鍵接口QPS減少80%以上。
平臺(tái)化(2017.1~now)是現(xiàn)在正在做的事情。面對(duì)UPS、廣告、商品多套引擎系統(tǒng)與廣告、搜索多套投放系統(tǒng)分別從不同團(tuán)隊(duì)合并過來, 維護(hù)成本問題。排序計(jì)算需求變得更加復(fù)雜,嘗試用非線性模型等方面挑戰(zhàn),就有了現(xiàn)在整理的架構(gòu),思路就是平臺(tái)化、統(tǒng)一化,把重復(fù)的系統(tǒng)整合、數(shù)據(jù)流做統(tǒng)一。
搜索架構(gòu)的探索之經(jīng)驗(yàn)總結(jié)
這一路走來,整個(gè)搜索架構(gòu)的探索經(jīng)驗(yàn)就是在發(fā)展前期要簡單快速支持線上業(yè)務(wù),之后在逐步演變,來滿足算法的需求,最后在考慮整個(gè)利用平臺(tái)化、統(tǒng)一化的思路去提升效率,降低成本。
不同階段要有不同的選擇,我們最早基于Solr改寫,待團(tuán)隊(duì)、人員,包括技術(shù)儲(chǔ)備上也有實(shí)力后,直接重寫搜索引擎,覆蓋算法的離線、在線鏈路,做體系化建設(shè)。
我們的后續(xù)規(guī)劃是新架構(gòu)整體平臺(tái)化繼續(xù)深入,算法方面加強(qiáng)學(xué)習(xí),如深度學(xué)習(xí)、在線學(xué)習(xí)等。如深度學(xué)習(xí)框架的研究和使用,以及圖搜工程體系的建設(shè)。
推薦架構(gòu)的探索之發(fā)展概述
蘑菇街的推薦架構(gòu)已經(jīng)覆蓋大部分的用戶行為路徑,從使用進(jìn)入APP,到下單成交完成都會(huì)有推薦場(chǎng)景出現(xiàn)。推薦架構(gòu)的整個(gè)發(fā)展分為發(fā)展早期(2103.11~2015.6)、1.0時(shí)期:從0到1(2015.6~2016.3)、2.0:投放+個(gè)性化(2016.3~2016.12)、3.0:平臺(tái)化(2016.2~now)四大階段。
發(fā)展早期(2103.11~2015.6)推薦的場(chǎng)景并不多,需求也比較簡單,數(shù)據(jù)離線更新到Redis就好,當(dāng)時(shí)明顯的問題是沒有專門的推薦系統(tǒng)來承載推薦場(chǎng)景、效果跟蹤差、場(chǎng)景對(duì)接、數(shù)據(jù)導(dǎo)入等效率低等。
1.0時(shí)期的推薦架構(gòu)
1.0時(shí)期:從0到1(2015.6~2016.3)把推薦系統(tǒng)搭建起來,包含Service層對(duì)接場(chǎng)景、推薦實(shí)時(shí)預(yù)測(cè)、自寫的K-V的系統(tǒng)用來存儲(chǔ)推薦結(jié)果。這里踩的一個(gè)坑是,把實(shí)時(shí)預(yù)測(cè)做到離線部分,但其實(shí)實(shí)時(shí)預(yù)測(cè)更多的是在線流程。
隨著時(shí)間推移,場(chǎng)景類型(猜你喜歡、搜相似、店鋪內(nèi))、相似場(chǎng)景(首頁、購物車、詳情頁…)不斷增加,算法方面需要實(shí)時(shí)排序,應(yīng)對(duì)實(shí)時(shí)的點(diǎn)擊、加購等,還有一些個(gè)性化排序需求,如店鋪、類目、離線偏好等。1.0階段主要面臨三大問題:
- 多類型多場(chǎng)景:上線系統(tǒng)不一,缺少統(tǒng)一對(duì)接層,成本高;
- 場(chǎng)景配置化:場(chǎng)景算法一對(duì)一,重復(fù)代碼拷貝,維護(hù)難;
- 個(gè)性化+實(shí)時(shí):缺系統(tǒng)支持;
2.0時(shí)期的推薦架構(gòu)
如上圖,2.0時(shí)期的推薦架構(gòu)(2016.3~2016.12)主要解決1.0的三大問題,增加投放層Prism,統(tǒng)一對(duì)外對(duì)接不同的業(yè)務(wù)場(chǎng)景,對(duì)Prism做動(dòng)態(tài)配置和規(guī)則模板。個(gè)性化實(shí)時(shí)方面增加UPS與精排系統(tǒng)。
2.0時(shí)期推薦架構(gòu)投放層配置化
如上圖,2.0時(shí)期推薦架構(gòu)投放層配置化思路是把不變的部分模板化,可變的部分配置化。系統(tǒng)提供召回組建、數(shù)據(jù)補(bǔ)全、格式化等模板。當(dāng)時(shí)效果很明顯,321大促運(yùn)營位置個(gè)性化效果提升20%+,雙11大促,會(huì)場(chǎng)樓層個(gè)性化提升100%+。
大促帶來的巨大收益,給整個(gè)系統(tǒng)帶來很正面的影響,后續(xù)推薦架構(gòu)又面臨更多的需求與挑戰(zhàn):
- 日益增長的資源位、直播、圖像等場(chǎng)景和類型;
- 跟美的融合,跨團(tuán)隊(duì)跨地域的挑戰(zhàn);
- 工程算法用一套代碼,整個(gè)策略的開發(fā)調(diào)試都非常復(fù)雜,包括工程部分的職責(zé)不清問題;
- 由于原來模板化的配置,導(dǎo)致一些簡單場(chǎng)景復(fù)雜化。
針對(duì)這些問題,我們需要做的事情就是通用化、平臺(tái)化。針對(duì)整套系統(tǒng)進(jìn)行統(tǒng)一推薦方案,自動(dòng)化整體算法對(duì)接核心業(yè)務(wù)流程、以及和算法人員的職責(zé)劃分清晰,提升雙方的工作效率。
3.0時(shí)期推薦架構(gòu)
3.0時(shí)期推薦架構(gòu) (2016.2~now)與搜索架構(gòu)類似,系統(tǒng)間職能更加明晰,統(tǒng)一和平臺(tái)化,主要還是投放層做了改造。
3.0時(shí)期推薦架構(gòu)投放層細(xì)節(jié)
如上圖, 3.0時(shí)期推薦架構(gòu)投放層重要的概念就是場(chǎng)景化,場(chǎng)景應(yīng)對(duì)推薦業(yè)務(wù),不同場(chǎng)景會(huì)對(duì)應(yīng)不同的策略實(shí)現(xiàn)。
推薦架構(gòu)的探索之總結(jié)
推薦架構(gòu)前期,也和搜索架構(gòu)一樣,需要快速支持推薦業(yè)務(wù),不需要花費(fèi)大量精力去搭建非常復(fù)雜的系統(tǒng)。滿足業(yè)務(wù)、算法等需求后,才是平臺(tái)化提升算法、工程雙方的效率。后續(xù)平臺(tái)化繼續(xù)深入,如針對(duì)算法策略的評(píng)測(cè)和壓測(cè)工具方面,全場(chǎng)景智能監(jiān)控報(bào)警&容災(zāi)。算法支持方面,就是OnlineLearning&強(qiáng)化學(xué)習(xí),根據(jù)算法效果來設(shè)計(jì)新產(chǎn)品。
更多細(xì)節(jié),請(qǐng)觀看演講視頻:http://edu.51cto.com/course/course_id-9255.html
【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文作者和出處為51CTO.com】