一、需求是什么?
互聯(lián)網(wǎng)中的許多應(yīng)用都有數(shù)據(jù)實(shí)時更新的需求,比如網(wǎng)頁搜索如何展示幾分鐘之前的新聞結(jié)果,購物搜索中價格、庫存信息的實(shí)時更新。在大數(shù)據(jù)量的情況下,數(shù)據(jù)如何做到穩(wěn)定及時的更新?本文以有道購物搜索(惠惠網(wǎng))價格更新為例,介紹一下數(shù)據(jù)實(shí)時更新系統(tǒng)的服務(wù)器端設(shè)計方案。
1.1 痛點(diǎn)之一:大數(shù)據(jù)不管是網(wǎng)頁搜索的時效性內(nèi)容展示,還是購物搜索海量商品的價格、庫存信息。都是單機(jī)較難承受的,同時,大數(shù)據(jù)對系統(tǒng)的可擴(kuò)展性,以及運(yùn)維的穩(wěn)定性都提出了挑戰(zhàn)。網(wǎng)頁搜索是幾百億量級,購物搜索是幾億商品量級。
1.2 痛點(diǎn)之二:實(shí)時性如果只是大數(shù)據(jù),我們可以用時間換空間,傳統(tǒng)的慢慢的批量更新就好。但很多實(shí)際應(yīng)用,用戶需要第一時間掌握最新的消息(網(wǎng)頁搜索場景,分鐘級別的最新新聞),用戶可能幾分鐘之內(nèi)就下單,需要了解當(dāng)前最準(zhǔn)確的價格和庫存信息(購物場景,熱門商品價格和庫存變化之后,分鐘級別的更新到前臺)。實(shí)時性不可或缺。
下面具體展示幾個使用到實(shí)時價格和庫存等信息的產(chǎn)品例子。如圖 1 所示,購物搜索的詳情頁中展示了多個來自價格服務(wù)器的相關(guān)信息。其中用紅色橢圓標(biāo)記的商品價格即為商品的實(shí)時價格,用藍(lán)色橢圓標(biāo)記的價格變化趨勢是對商品歷史價格的變動趨勢概括,用土黃色橢圓標(biāo)記的庫存狀態(tài)表示該商城的此商品已經(jīng)處于缺貨狀態(tài)。通過點(diǎn)擊“價格下降”的趨勢圖標(biāo),可以彈出圖 2 所示的該商品的價格歷史截圖。不僅購物搜索會使用到實(shí)時的價格和庫存數(shù)據(jù),購物助手在展示比價和價格歷史的時候也使用了實(shí)時的價格數(shù)據(jù),如圖 3 所示,藍(lán)色圈起來的是價格歷史,紅色圈起來的是其它商家的實(shí)時價格。
圖1 搜索詳情頁中價格服務(wù)提供的數(shù)據(jù)截圖
圖2 索尼HX10數(shù)碼相機(jī)的價格歷史截圖
圖3 購物助手的展示示例
通過以上產(chǎn)品展示,我們知道在購物搜索與比價等產(chǎn)品中,精準(zhǔn)的價格與庫存信息直接影響著用戶對產(chǎn)品的信賴。因此,這些關(guān)鍵數(shù)據(jù)的更新速度對整個產(chǎn)品而言就變得至關(guān)重要。在傳統(tǒng)的搜索引擎系統(tǒng)中,數(shù)據(jù)的抓取與更新一般由后臺驅(qū)動完成,即:以固定的時間以一定的頻率和策略進(jìn)行數(shù)據(jù)抓取,抓到的數(shù)據(jù)與用戶的查詢之間有一段“不可接受的”的時間間隔,而這段數(shù)據(jù)緩存時間往往導(dǎo)致數(shù)據(jù)過期,使得搜索的結(jié)果不夠準(zhǔn)率。對于購物搜索而言,目前的大型電商網(wǎng)站的商品價格經(jīng)常會變動,平均每分鐘 B2C 價格變化的商品大概在 1500 左右。后臺的批量抓取在價格更新方面往往不夠及時,為了在任意時刻都能夠?yàn)橛脩籼峁└鼫?zhǔn)確的商品價格,我們?yōu)樘幚砩唐穬r格開發(fā)了一個新的服務(wù),價格服務(wù)器。
價格服務(wù)器這個數(shù)據(jù)實(shí)時更新系統(tǒng)的設(shè)計需要解決兩個關(guān)鍵的問題:1、大規(guī)模數(shù)據(jù)抓取與更新,滿足用戶商品檢索需求的購物商品數(shù)是幾億量級。2、價格、庫存數(shù)據(jù)的實(shí)時性。商品價格/庫存變化,希望能做到分鐘級別的更新,尤其是用戶關(guān)注瀏覽的熱門商品。這些大量數(shù)據(jù)的更新能力,主要取決于我們自身的抓取能力,同時還依賴于目標(biāo)電商網(wǎng)站的承受能力。而且價格數(shù)據(jù)的實(shí)時性則關(guān)系到用戶對產(chǎn)品的信賴度,直接影響著用戶在搜索或比價結(jié)果中作出的選擇。同時,價格的實(shí)時性也關(guān)系著所有依賴于它的其它服務(wù)的實(shí)效性,因?yàn)樵趦r格更新的同時,也會觸發(fā)全網(wǎng)比價和降價提醒等服務(wù)的數(shù)據(jù)更新。
二、整體架構(gòu)設(shè)計價格服務(wù)器的整體架構(gòu)設(shè)計包含了兩方面的特性:分布式特性和實(shí)時特性。下面分別介紹其必要性和具體實(shí)現(xiàn)。
2.1 分布式特性隨著電商行業(yè)的飛速發(fā)展,商品的數(shù)量也在不斷的快速增加,集中式結(jié)構(gòu)的 可擴(kuò)展性相對較差,因此整個系統(tǒng)必須使用分布式的體系,將繁雜的不同的任務(wù)分配給若干個獨(dú)立的系統(tǒng)并行處理,能夠極大地提高了系統(tǒng)的性能和可擴(kuò)展性。
如圖4 所示,價格服務(wù)器的分布式體系中主要由三種服務(wù)構(gòu)成:任務(wù)調(diào)度服務(wù)器、抓取服務(wù)器、結(jié)果入庫服務(wù)器,分別對應(yīng)圖中的 PriceServer、PriceUpdateServer 和 PriceWriteBackServer,這三種服務(wù)采用 RPC(遠(yuǎn)程過程調(diào)用)的方式進(jìn)行相互調(diào)用。其中任務(wù)調(diào)度服務(wù)器同時提供對外數(shù)據(jù)查詢的功能。由于系統(tǒng)的分布式特性,這三種服務(wù)每個都可以有多個實(shí)例,可以根據(jù)系統(tǒng)的實(shí)際需求隨時進(jìn)行擴(kuò)容。其中,最先可能遇到瓶頸的就是抓取服務(wù)器,分布式的架構(gòu)可以簡單快捷地通過增加機(jī)器來對系統(tǒng)擴(kuò)容,進(jìn)而增加系統(tǒng)的抓取能力。分布式特性同時可以提高系統(tǒng)的穩(wěn)定性,當(dāng)某一臺服務(wù)不可用時,同類別的其它服務(wù)器仍可以正常運(yùn)行,減少由于服務(wù)宕機(jī)導(dǎo)致產(chǎn)品不能使用的概率。
圖4 價格服務(wù)器的層次結(jié)構(gòu)
2.2 實(shí)時特性整個系統(tǒng)的實(shí)時特性主要體現(xiàn)在兩個方面:1、數(shù)據(jù)更新的實(shí)時性;2、數(shù)據(jù)變化后通過其它服務(wù)的實(shí)時性。
2.2.1 基于查詢的實(shí)時抓取在海量的商品面前,由于抓取能力有限,根本無法滿足快速地更新所有的商品的價格信息,為了保證用戶對于數(shù)據(jù)高實(shí)時性的要求,應(yīng)該盡可能地優(yōu)先保證熱門商品的數(shù)據(jù)更新,所以實(shí)時抓取的商品選擇是比較關(guān)鍵的。我們的系統(tǒng)使用購物助手的瀏覽記錄以及購物搜索的查詢記錄當(dāng)作熱門商品。具體流程為:用戶瀏覽某商品,購物助手獲取該用戶所瀏覽的商品 URL 以及其它商城該商品的 URL 列表發(fā)送到任務(wù)調(diào)度服務(wù)器,任務(wù)調(diào)度服務(wù)器根據(jù)上一次抓取的價格時間等信息來進(jìn)行調(diào)度,將任務(wù)分配至抓取服務(wù)器,抓取服務(wù)器解析到新的價格后發(fā)送到結(jié)果入庫服務(wù)器。結(jié)果入庫服務(wù)器完成數(shù)據(jù)的更新,并通知其它價格事件監(jiān)聽程序。這就完成了整個基于查詢驅(qū)動的實(shí)時抓取的過程。這種實(shí)時抓取策略就叫做“查詢驅(qū)動抓取”(簡稱 QTC,Query Triggered Crawling)。
2.2.2 數(shù)據(jù)變化的實(shí)時通知價格服務(wù)器除了實(shí)時抓取和管理所有商品的價格之外,還需要向其它服務(wù)(如降價提醒、全網(wǎng)比價等)提供價格變化的更新事件。如何使得其它服務(wù)可以實(shí)時地得到商品的價格變化信息呢?我們首先介紹一下觀察者模式。
觀察者模式(也被稱為發(fā)布/訂閱模式)是軟件設(shè)計模式的一種。在此種模式中,一個目標(biāo)對象管理所有相依于它的觀察者對象,并且在它本身的狀態(tài)改變時主動發(fā)出通知。這通常透過呼叫各觀察者所提供的方法來實(shí)現(xiàn)。此種模式通常被用來實(shí)作事件處理系統(tǒng)。
觀察者模式已經(jīng)在數(shù)據(jù)變化的實(shí)時通知方面被廣泛地應(yīng)用,它使得服務(wù)具有高類聚、低耦合的特點(diǎn)。下面來介紹兩個使用了類似觀察者模式的成熟的系統(tǒng),分別是 Google的咖啡因(Google Caffeine)索引系統(tǒng)和 Linkedin 的 Databus 數(shù)據(jù)傳輸總線。
圖5 Google 咖啡因架構(gòu)
圖 5 是 Google 的咖啡因索引架構(gòu):Percolator 是基于分布式存儲系統(tǒng) BigTable 的,核心在于實(shí)現(xiàn)了對每個文檔的隨機(jī)訪問。Percolator 的觀察者模式(observer)可以在底層數(shù)據(jù)特定列發(fā)生更新之后,被系統(tǒng)調(diào)用,從而實(shí)現(xiàn)上層應(yīng)用的及時更新。在網(wǎng)頁搜索領(lǐng)域里,傳統(tǒng)的索引更新方案是基于 MapReduce 和其他批處理系統(tǒng)定時更新的,這使得索引的更新至少需要等待一輪完整的大數(shù)據(jù)處理流程完成。即使是一輪增量數(shù)據(jù)處理,相對于實(shí)際應(yīng)用需要,依然是漫長不太可接受的。
再來看另外一個架構(gòu),前不久,Linkedin 公布了一個其內(nèi)布使用的 Databus 項(xiàng)目。如圖 6 所示,Databus 的主要原理是當(dāng)任何數(shù)據(jù)庫有更新時,通過分析數(shù)據(jù)庫的更新日志,將所有的數(shù)據(jù)更新事件傳輸?shù)?Databus 總線上,進(jìn)而通過各個其它服務(wù)更新數(shù)據(jù)。數(shù)據(jù)源發(fā)生完成后,Databus 能在微秒級內(nèi)將事務(wù)提交給消費(fèi)者。同時,消費(fèi)者使用 Databus 中的服務(wù)器端過濾功能,可以只獲取自己需要的特定數(shù)據(jù)。
圖6 Linkedin 的 Databus 數(shù)據(jù)傳輸總線概要結(jié)構(gòu)
顯示易見,Databus 的設(shè)計思路與 Percolator 的觀察者模式非常相似。因此,我們在價格服務(wù)器中也使用了類似的設(shè)計,將實(shí)時更新的價格變化事件通知到一系列其它的產(chǎn)品服務(wù)中(如降價提醒、全網(wǎng)比價等)。
如圖 7 所示,在價格服務(wù)器的系統(tǒng)中,結(jié)果入庫服務(wù)器是所有價格數(shù)據(jù)更新的必經(jīng)之地,它從數(shù)據(jù)源得到最新的價格數(shù)據(jù),通過對比底層存儲中的舊數(shù)據(jù),就可以直接獲取到所有的價格變化,進(jìn)而更新數(shù)據(jù)庫中的價格、歷史、趨勢等信息。它利用觀察者模式,將所有的價格變化事件傳送到其它監(jiān)聽服務(wù)(如降價提醒、全網(wǎng)比價等)。每個監(jiān)聽服務(wù)會根據(jù)自身的需求過濾掉沒有用的事件,因此像降價提醒這種服務(wù)可以實(shí)時地提醒用戶某個商品的降價消息。
圖7 結(jié)果入庫服務(wù)器觸發(fā)其它服務(wù)的數(shù)據(jù)流程
同時,如圖 7 所示,結(jié)果入庫服務(wù)器還會將所有的價格更新信息以日志的形式記錄下來,后臺的非實(shí)時的分析工具通過這些日志構(gòu)建價格歷史、電商價格報表等。
三、數(shù)據(jù)源如圖 8 所示,價格服務(wù)器的價格更新主要來源有三個:1、抓取服務(wù)器的實(shí)時抓取;2、合作電商主動提供的數(shù)據(jù);3、后臺定時批量抓取和解析的流程。
圖8 商品價格數(shù)據(jù)來源
這三種數(shù)據(jù)更新來源,最能保證數(shù)據(jù)實(shí)效性的是抓取服務(wù)器的實(shí)時抓取,前文已經(jīng)描述它的工作原理。雖然實(shí)時抓取可以最大程度地滿足用戶查詢結(jié)果的實(shí)效性,但是覆蓋率相對較低,因此還需要其它數(shù)據(jù)源的配合才能提高商品價格更新的覆蓋率。和絕大多數(shù)搜索引擎相同,購物搜索的后臺也會定時批量地抓取大量的商品數(shù)據(jù)。同時,我們與一些商家進(jìn)行了合作,這些商家會定時主動向我們的系統(tǒng)推送他們最新的商品數(shù)據(jù),這些數(shù)據(jù)也包括價格和庫存等信息。有了后臺定時批量抓取流程和合作商家的推送數(shù)據(jù),幾乎就使得絕大多數(shù)商品的數(shù)據(jù)可以得到及時地更新了。
除此之外,還會利用其它服務(wù)的日志離線觸發(fā)價格服務(wù)器更新用戶感興趣的商品的價格數(shù)據(jù)。例如:利用用戶訂閱的降價提醒商品列表定期更新這些用戶感興趣的商品的價格。又如:全網(wǎng)比價展示了所有最新降價的商品,這些商品的價格是否又回升了對全網(wǎng)比價的質(zhì)量影響很大,因此,全網(wǎng)比價的商品列表也需要經(jīng)常被更新,以防止過時的降價信息影響用戶體驗(yàn)度。
總結(jié)一下,數(shù)據(jù)來源的使用主要有三點(diǎn)。第一、盡可能地利用多種數(shù)據(jù)來源,使價格能夠被更快速及時地更新;第二、首先保證熱門商品的價格被及時更新,熱門商品的列表來自于用戶的瀏覽記錄與搜索歷史等;第三、不能忽略非熱門的商品,非熱門商品雖然被用戶訪問的次數(shù)少,但也需要定期地被更新,只是更新間隔略長一些。
四、總結(jié)本文主要以購物搜索價格服務(wù)器,輔以 Google 咖啡因,Linkedin 的 Databus 為例,介紹了大數(shù)據(jù)實(shí)時更新框架的設(shè)計思想??蚣艿墓餐c(diǎn)是:1、觀察者模式,2、細(xì)粒度的更新數(shù)據(jù)到應(yīng)用層。對比過去 MapReduce 的批量更新機(jī)制,更好的解決了大數(shù)據(jù)和實(shí)時性這兩大痛點(diǎn)。