1. 程式人生 > >大型廣告系統架構 — 檢索模組

大型廣告系統架構 — 檢索模組

廣告系統主要解決一個問題:在給定展示場景、使用者的情況下,返回收益最大化的廣告。下圖是一個廣告系統最簡單的架構圖。其中,Router,檢索模組,排序模組一般稱為廣告系統的核心。同時,與之輔助的至少包含三大系統:特徵計算系統,計費系統,投放系統。


先介紹一下三個輔助系統的主要功能:

  • 特徵計算系統:實時計算廣告展示環境 (網頁,APP) 的特徵,使用者的特徵。並提供實時查詢功能。

  • 計費系統:實時處理廣告的展現 (CPM)、點選 (CPC)、轉化 (CPA)資料,並計算廣告的剩餘預算。需要包括反作弊功能。

  • 投放系統:供廣告主使用,設定廣告的基本資訊和定向條件。

核心部分包含了三個模組:

  • Router:對外提供HTTP服務。接收請求後,依次與特徵計算系統、檢索模組、排序模組互動,最後返回廣告。

  • 檢索模組:檢索模組主要解決相關性問題。首先,根據廣告主設定的定向條件篩選出本次請求能否返回的廣告;然後,按多種定向策略篩選出與本次請求最相關的若干個廣告。

  • 排序模組:排序模組主要解決收益最大化的問題。通用的排序標準是eCPM。以CPC廣告系統為例,eCPM=eCTR*CPC,CPC是廣告主設定的,排序模組的核心就是使預估的eCTR儘可能地接近實際CTR。

本文討論檢索模組的架構設計。在檢索模組中使用的資料一般可以分為三類:

  1. 廣告本身的資訊。例如ID,標題,描述,出價,投放時間,預算餘額等。

  2. 廣告的定向資料。例如國家,裝置,人群等。

  3. 各個定向策略使用的內部資料。例如,預先計算出的各個廣告的特徵,人群的興趣點擴充資料等。

同樣,討論架構先說業務特點。

  1. 大型廣告系統中,單機的瓶頸首先出現在記憶體上,通常記憶體的使用率在80%以上,只剩餘20%的記憶體空間實際上是非常危險的,後文中會闡述原因。在使用的記憶體中,可以假定70%是廣告資料,30%是各策略使用的內部資料。

  2. 資料的更新量佔資料總量的比例很小,一般更新量會比總量少兩個數量級。

  3. 資料存在熱點。例如,一些熱門搜尋詞會被大量廣告主購買,一些熱門的人群也會被廣告主大量購買。

帶著這些前提,接下來討論檢索模組的幾個主要問題。


  • 冷啟動

檢索模組在提供服務前,需要將最新的廣告資料和策略資料載入到記憶體中。假定檢索模組使用的是記憶體為64G的機器,按記憶體使用率80%計算,系統啟動的時候需要把50G的資料載入到記憶體,可以想象這是一個耗時很長的操作。另外,廣告系統一般都包含正排索引和倒排索引兩種資料,倒排索引是根據正排索引建立的,所以系統啟動的時候不僅僅是載入資料,還存在計算的過程,當然,在不存在指標的情況下,倒排索引也可以預先計算好,可以減少啟動時間。

全量與增量。因為廣告資料是實時在變化的,所以一般的方案是定期對資料庫做快照,並記錄下時間點。系統啟動時,載入最新的一個快照的資料,並且載入完所有該快照生成時間之後的所有更新,才可以對外提供服務。快照一般稱為全量,更新一般稱為增量。另外,這裡說的時間,不一定是真實的時間,也可以是邏輯時間。例如,建立一個高可用服務,對外提供始終自增的id,每一條資料更新都關聯一個唯一的id,做快照的時候,快照的id就是最新一條記錄的id。

預生成索引檔案。資料庫的快照一般是以文字檔案的形式儲存的。但是,系統在啟動的時候處理文字檔案,是非常耗時的。所以一般會使用一臺單獨的機器預先載入快照檔案,將資料轉換為與檢索模組相同的二進位制的格式,再dump到二進位制檔案中,這樣檢索模組啟動的時候直接載入二進位制檔案,可以達到很好的效能。注意,為了提高載入資料的效率,二進位制資料往往沒有經過任何序列化,因此建立索引的服務必須使用和檢索模組同樣的作業系統和配置。

  • 記憶體資料結構設計

檢索模組使用的資料結構必須具備兩個特性:高效儲存,高效更新。

高效儲存是指如何使用盡可能小的記憶體空間儲存給定的資料。因此工程師需要對記憶體進行精確的控制(記憶體中的資料排列,分配和釋放),這也是為什麼大多數對記憶體要求嚴格的系統都使用C/C++開發的原因(無意引起語言之爭)。位操作在檢索模組中很常見,同時在設計結構體時,要充分考慮資料對齊(可參考的資料很多,這裡不展開)。下面重點介紹兩種常見的技術。

MemoryPool

MemoryPool是C++中常用的記憶體分配技術。大的物件或陣列往往是分配在堆上,系統中時刻都有不同的物件被建立和銷燬,如果每次都使用 malloc/free 去建立/銷燬物件,則容易造成記憶體碎片。MemoryPool的作用是,為常見的物件批量申請記憶體並預留,在系統需要建立物件的時候,從預留的記憶體中選擇一塊空間,作為新的物件,供系統初始化和使用。在銷燬物件時,並沒有實際銷燬這段記憶體空間,而是將該空間記錄在MemoryPool內部的列表中 (freelist),在下次分配空間的時候優先從該列表分配。

常見的MemoryPool提供Create和Destroy兩個方法。

  • Create即建立一個物件,如果MemoryPool中有預留的空間,則在預留的空間上分配,否則批量向系統申請空間。為了提供效率,Create方法常常返回指標而不是ID,因此MemoryPool不能移動其內部已經分配的空間。在Create方法返回後,常見的是使用Placement Constructor初始化物件。

  • Destroy方法接受指標作為引數,該指標指向的記憶體地址必須是MemoryPool分配的。Destroy方法可以呼叫物件的解構函式,然後將該指標加入到freelist。

以上討論的是固定長度的MemoryPool,一般一個結構體對應一個MemoryPool。還有另一種可以儲存多種長度的物件的MemoryPool,在實際使用中比較少見,想了解這方面的設計可以參考TCMalloc。

B+樹

B樹及其變種是資料庫常用的資料結構。在記憶體-磁碟式資料庫中,類B樹的資料結構允許系統只將一部分節點載入到記憶體;在全記憶體資料庫中,類B樹的資料結構允許系統只將一部分節點的資料放入CPU的快取中。類B樹的資料主要有以下幾個優點:

  1. 資料的插入和刪除效能相對穩定。

  2. 在記憶體不足時,允許只將使用者查詢的索引資料全部或部分放入記憶體,提高查詢效率

  3. 在執行新增和刪除操作是,只需要修改很少的節點(修改次數與Fanout有關)

  4. locality性比較好,尤其在系統存在熱點資料的情況下更為明顯。

實際使用中,B+樹是比B樹更好的選擇。B+樹相比B樹,主要有兩個優點:

  1. 索引和資料相分離,內部節點只儲存索引資料。記憶體中相同大小的內部節點,B+樹可以儲存更多的索引。

  2. 葉子節點儲存了全部的資料,並且葉子節點通過指標關聯,可以方便地按順序遍歷全部或者部分資料。

B+樹在使用過程中最常見的問題是,往往由於使用方式的不當,導致節點沒有被填滿,導致巨大的記憶體浪費。

在實際實現中,B+樹的節點往往會根據Fanout預留全部的記憶體空間。以插入資料為例,在節點發生分裂時,分裂後的兩個節點都會有一定的空間未被使用,如果沒有合理地選擇插入資料的順序,會造成大量的節點未被充分使用。

例如,我們要將1到10十個數字插入到一顆空的B+樹種,如果順序插入,會得到如下的結果:



如果我們熟悉B+樹的分裂策略,再稍微仔細的計算一下插入順序,會得到不同的結果:


可以看到,順序插入使用了導致B+樹生成了八個節點,打亂一下次序只需要七個節點即可。不要小看這一個節點,當Fanout很大時,會節省非常可觀的記憶體。筆者曾經通過優化B+樹的內部組織,為單機節省了7G的記憶體。

細心的讀者可以發現,在已知全部資料的情況下,是可以計算出插入B+樹的最優方案的。前文提過,廣告系統的資料更新量相比全量會少兩個數量級,因此係統啟動結束之後,記憶體的佈局基本也就固定了,另外系統會隨著上線被頻繁重啟,因此,解決了系統啟動時候B+樹的記憶體佈局,也就解決了大部分問題。B+樹的最優插入方案留給讀者去思考。

  • 資料更新

廣告的資料和策略使用的資料都需要更新,但特點不同。廣告資料對實時性要求非常高,廣告主期望在秒級更新,但一天的更新量可能只佔全量的1%不到。策略使用的資料往往需要通過大量的離線計算才能生成,往往幾個小時甚至一天才需要更新一次,但更新的量很大,可能大部分資料都需要被更新。

增量更新 (INC)

廣告資料對實時性要求高,因此一般採用增量更新的方案。回想本文開始的檢索端架構圖,投放系統和計費系統將廣告資料更新到DB,同時傳送給Message Queue,MQ中的每條資料都帶著一個表示邏輯時間的ID。在各個檢索模組的伺服器上部署一個單獨的服務從MQ訂閱資料,該服務在接收到資料後,將資料以檔案的形式持久化到磁碟。檢索模組中有一個執行緒,定期從檔案中讀取更新的增量資料,並更新到記憶體中。

難點在於,檢索模組在資料更新的同時,還需要繼續提供服務,不能出現因為更新資料而鎖住資料的情況。回想前文所說的,為了提高效率,系統中的資料都使用MemoryPool儲存,MemoryPool對外暴露的都是指標,在一次請求過程中基本都在通過指標讀取資料,很少有Copy資料的情況。因此,不能修改當前正在檢索的資料。

這裡一般使用Copy-On-Write的更新策略。即,同一個Key關聯的資料有多個版本,在更新資料時,不更新原始的資料,而是Copy一份原有資料,並在此基礎上最修改,新的資料比原有資料的版本號更大。在更新的過程中,老版本的資料依然可用;在下次查詢中,返回的是最新版本的資料,同時在合適的時機刪除老版本的資料。事實上,這個策略在目前的NoSQL系統中普遍存在。

Copy-On-Write的難點在於,如果保證Copy的資料儘量的小,最好只Copy更新的那個資料(實際上很難實現)。結合上文,讀者可以考慮如何實現一個支援多版本資料的B+樹,並且在Copy的時候儘可能少地Copy節點。

全量更新 (Reload)

策略資料對實時性要求不高,但更新的數量可能會很大,一般會使用Reload的方式進行更新。Reload更新最典型的方案是雙Buffer切換。即,將新的資料全部匯入到一個新的資料物件(Hash表)中,匯入完畢後,使用新的物件替代老的物件。

Reload方法更新的資料,最大的好處是可以假定記憶體中的資料結構是隻讀的,不會出現增量更新方式中對資料結構進行插入和刪除的操作。因此,可以使用一些更加簡單高效的資料結構。

如果使用雙Buffer切換的方式進行Reload資料,需要注意在更新的過程中,該資料的記憶體使用量會翻倍;如果多份資料同時進行Reload,會導致記憶體使用突然激增,甚至會超出系統極限,導致程式崩潰。這樣的案例在生產環境中真實的出現過,雖然系統會自動重啟,但如果大量機器同時觸發這個情況,會出現非常危險的雪崩效應。這也是前文提到的,系統的記憶體使用量在80%以上,其實是有很大的風險的原因。因此,在多份資料都使用Reload的方案更新時,要注意好控制記憶體的使用,通過一些機制避免多個任務並行。

作為大型廣告系統的核心,檢索模組面臨的問題非常複雜,實際的架構設計要緊密結合業務進行展開。沒有統一的方案,只有不同的權衡妥協。本文重點討論了檢索模組一些常見的問題和解決方案,其中有很多細節留給讀者思考。


關注我的公眾號架構叢談 最樸素地談架構


相關推薦

大型廣告系統架構檢索模組

廣告系統主要解決一個問題:在給定展示場景、使用者的情況下,返回收益最大化的廣告。下圖是一個廣告系統最簡單的架構圖。其中,Router,檢索模組,排序模組一般稱為廣告系統的核心。同時,與之輔助的至少包含三大系統:特徵計算系統,計費系統,投放系統。 先介紹一下三個輔助

大型廣告系統架構概述

在網際網路江湖中,始終流傳著三大賺錢法寶:廣告、遊戲、電商。三傑之中,又以大哥廣告的歷史最為悠久,地位也最為不可撼動。君不見很多電商和遊戲公司,也通過廣告業務賺的盆滿鉢滿。其發跡於Y公司,被G公司發揚光大,又在F公司階段性地完成了其歷史使命。F公司,在移動網際網路興

淺談大型web系統架構

memcache hbm 設備 應用服務器 syn sql 執行 效率 color CSDN文章:淺談大型web系統架構(丁碼農) 動態應用,是相對於網站靜態內容而言,是指以c/c++、php、Java、perl、.net等服務器端語言開發的網絡應用軟件,比如論壇、網絡相冊

P9架構師講解從單機至億級流量大型網站系統架構的演進過程

獲取域名 哈希算法 相關 方案 nat 可靠的 發布 成了 反向 階段一、單機構建網站 網站的初期,我們經常會在單機上跑我們所有的程序和軟件。此時我們使用一個容器,如tomcat、jetty、jboos,然後直接使用JSP/servlet技術,或者使用一些開源的框架如mav

阿里P9架構師講解從單機至億級流量大型網站系統架構的演進過程

階段一、單機構建網站 網站的初期,我們經常會在單機上跑我們所有的程式和軟體。此時我們使用一個容器,如tomcat、jetty、jboos,然後直接使用JSP/servlet技術,或者使用一些開源的框架如maven+spring+struct+hibernate、maven+

阿里P9架構師簡述從單機至億級流量大型網站系統架構的演進過程

階段一、單機構建網站 網站的初期,我們經常會在單機上跑我們所有的程式和軟體。此時我們使用一個容器,如tomcat、jetty、jboos,然後直接使用JSP/servlet技術,或者使用一些開源的框架如maven+spring+struct+hibernate、maven+

大型web系統架構詳解

源代碼管理 可能 com 統一 服務器管理 交友 存在 web前端 登陸 動態應用,是相對於網站靜態內容而言,是指以c/c++、php、Java、perl、.net等服務器端語言開發的網絡應用軟件,比如論壇、網絡相冊、交友、BLOG等常見應用。動態應用系統通常與數據庫系統、

一個成熟的大型網站系統架構演化之路

二、應用、資料、檔案分離 隨著業務的擴充套件,一臺伺服器已經不能滿足效能需求,故將應用程式、資料庫、檔案各自部署在獨立的伺服器上,並且根據伺服器的用途配置不同的硬體,達到最佳的效能效果。 三、利用快取改善網站效能 在硬體優化效能的同時,同時也通過軟體進行效能優化,在大部分的網站系統中,都會利

大型網站系統架構的演化

前言     一個成熟的大型網站(如淘寶、京東等)的系統架構並不是開始設計就具備完整的高效能、高可用、安全等特性,它總是隨著使用者量的增加,業務功能的擴充套件逐漸演變完善的,在這個過程中,開發模式、技術架構、設計思想也發生了很大的變化,就連技術人員也從幾個人發展到一個部門甚至一條產品線。所以成熟的系統架構是

網際網路DSP廣告系統架構及關鍵技術解析 | 廣告行業資深架構師親述

http://www.360doc.com/content/15/0806/07/2909773_489803369.shtml 此文是根據付海軍在【QCON高可用架構群】中的分享內容整理而成,轉發請註明出處。 付海軍,現就職於時趣互動,任技術總監,負責移動原生廣告平臺引擎開發和資料探勘工作,06年畢業

大型網站系統架構分析整理

千萬級的註冊使用者,千萬級的帖子,nTB級的附件,還有巨大的日訪問量,大型網站採用什麼系統架構保證效能和穩定性? 首先討論一下大型網站需要注意和考慮的問題。 資料庫海量資料處理:負載量不大的情況下select、delete和update是響應很迅速的,最多加幾個索引就可以搞

從程式設計小白到架構總監:大型網站系統架構演化之路

前言 一個成熟的大型網站(如淘寶、京東等)的系統架構並不是開始設計就具備完整的高效能、高可用、安全等特性,它總是隨著使用者量的增加,業務功能的擴充套件逐漸演變完善的,在這個過程中,開發模式、技術架構、設計思想也發生了很大的變化,就連技術人員也從幾個人發展到一個

Java面試題精選,大型網站系統架構你不得不懂的10個問題

百度 spring 運行 出現 網站 性能測試 企業 產品 多個 作者:JavaGuide(公眾號) 下面這些問題都是一線大廠的真實面試問題,不論是對你面試還是說拓寬知識面都很有幫助。之前發過一篇8 張圖讀懂大型網站技術架構 可以作為不太了解大型網站系統技術架構朋友的

大型網際網路系統架構是如何設計的?

接下來,我們將看看高階的權衡和取捨: 效能與可擴充套件性 延遲與吞吐量 可用性與一致性 記住每個方面都面

DSP廣告系統架構及關鍵技術解析(轉)

都是 用戶id 定義 log 運營商 歷史 9.png 整合 客戶 廣告和網絡遊戲是互聯網企業主要的盈利模式 廣告是廣告主通過媒體以盡可能低成本的方式與用戶達成接觸的商業行為。也就是說按照某種市場意圖接觸相應人群,影響其中潛在用戶,使其選

乾貨 | 廣告系統架構解密

廣告、增值服務、佣金,是網際網路企業最常見的三種盈利手段。在這3大經典中,又以廣告所佔的市場份額最大,幾乎是絕大部分網際網路平臺最主要的營收途徑,業務的重要性不言而喻。 從技術角度來說,廣告業務涉及到 AI演算法、大資料處理、檢索引擎、高效能和高可用的工程架構 等多個方向,同樣有著不錯的技術吸引力。 我從

大型網站技術架構:核心原理與案例分析》-- 讀書筆記 (5) :網購秒殺系統

案例 並發 刷新 隨機 url 對策 -- 技術 動態生成 1. 秒殺活動的技術挑戰及應對策略 1.1 對現有網站業務造成沖擊 秒殺活動具有時間短,並發訪問量大的特點,必然會對現有業務造成沖擊。對策:秒殺系統獨立部署 1.2 高並發下的應用、

說說大型高並發高負載網站的系統架構(轉載)

硬件 ip配置 cache 鏡像站 常見 tcp 兩個 資源 virtual 一個小型的網站,比如個人網站,可以使用最簡單的html靜態頁面就實現了,配合一些圖片達到美化效果,所有的頁面均存放在一個目錄下,這樣的網站對系統架構、性能的要求都很簡單,隨著互聯網業務的不斷豐富,

大型系統架構的核心要素-理論

應對 壓縮 數據存儲 路由算法 family 驅動 分布式服務 tro 可訪問性 1、性能 優化的方式有如下: 1)瀏覽器端: 通過瀏覽器緩存、頁面壓縮、合理布局頁面和減少cookie傳輸 2)應用服務器端:使用帶我去本地緩存和分布式緩存,通過緩存在內存的熱點 數據處理用戶

閱讀《大型網站技術架構:核心原理與案例分析》第五、六、七章,結合《河北省重大技術需求征集系統》,列舉實例分析采用的可用性和可修改性戰術

定時 並不會 表現 做出 span class 硬件 進行 情況   網站的可用性描述網站可有效訪問的特性,網站的頁面能完整呈現在用戶面前,需要經過很多個環節,任何一個環節出了問題,都可能導致網站頁面不可訪問。可用性指標是網站架構設計的重要指標,對外是服務承諾,對內是考核指