干貨 | 廣告系統架構解密

從技術角度來說,廣告業(yè)務涉及到?AI算法、大數據處理、檢索引擎、高性能和高可用的工程架構?等多個方向,同樣有著不錯的技術吸引力。
我從去年開始接觸廣告業(yè)務,到現在差不多一年時間了。這篇文章將結合我的個人經驗,同時參考業(yè)界的優(yōu)秀案例,闡述下廣告系統的架構實踐方案,希望讓大家有所收獲。內容包括以下3部分:
廣告業(yè)務簡介 面臨的技術挑戰(zhàn) 廣告系統架構詳解
01 廣告業(yè)務簡介
廣告,可以說無處不在。微信、抖音、B站、百度、淘寶等等,這些占據用戶時間最長的 APP, 到處都能看到廣告的影子。
我們每天隨處可見的廣告,它背后的業(yè)務邏輯到底是什么樣的呢?在分享廣告系統的架構之前,先給大家快速普及下業(yè)務知識。
1. 廣告業(yè)務的核心點是平衡
為什么說廣告業(yè)務的核心點是「平衡」?可以從廣告的標準定義來理解。
廣告被定義為:廣告主以付費方式通過互聯網平臺向用戶傳播商品或者服務信息的手段。這個定義中涉及到?廣告主、平臺、用戶?3個主體,但是這3個主體的利益關注點各不相同。

圖1:廣告業(yè)務的三角平衡
廣告主:關注ROI,花了錢是否能帶來預期收益
平臺:擁有流量,關注收益能否最大化
用戶:關注體驗,廣告是否足夠精準?是否影響到了正常功能的使用?
有時候這三者的利益是沖突的,比如平臺增加了廣告位數量,收益肯定增加,但用戶體驗可能變差,因此廣告業(yè)務最終要尋找的是三方的平衡。
站在平臺的角度來看廣告業(yè)務,它在保證用戶體驗的同時,要兼顧絕大部分廣告主的ROI(確保他們是可以賺到錢的),在此基礎上再考慮將平臺的收入最大化,這樣才是一個健康的廣告生態(tài)。
廣告業(yè)務發(fā)展了幾十年,廣告費用的結算方式也誕生了很多種,我們最常見的有以下幾種:
CPT:按時間計費,獨占性包時段包位置 CPM:按照每千次曝光計費 CPC:按照點擊計費 CPA:按照行為計費(比如下載、注冊等)

圖2:廣告費用的結算方式演進
之所以有不同的結算方式,其實也是隨著廣告市場的發(fā)展逐漸衍生出來的,最開始流量稀缺,平臺占優(yōu)勢,再到今天逐漸成了買方市場,廣告主作為需求方的談判權變大。

3. 廣告的核心業(yè)務流程

圖3:廣告的核心業(yè)務流程
廣告主先通過投放平臺發(fā)布廣告,可設置一系列的定向條件,比如投放城市、投放時間段、人群標簽、出價等。
投放動作完成后,廣告會被存放到廣告庫、同時進入索引庫,以便能被廣告檢索引擎召回。
C端請求過來后,廣告引擎會完成召回、算法策略、競價排序等一系列的邏輯,最終篩選出Top N個廣告,實現廣告的千人千面。
用戶點擊廣告后,會觸發(fā)廣告扣費流程,這時候平臺才算真正獲得收益。
1、高并發(fā):廣告引擎和C端流量對接,請求量大(平峰往往有上萬QPS),要求實時響應,必須在幾十毫秒內返回結果。
2、業(yè)務邏輯復雜:一次廣告請求,涉及到多路召回、算法模型打分、競價排序等復雜的業(yè)務流程,策略多,執(zhí)行鏈路長。
3、穩(wěn)定性要求高:廣告系統直接跟收入掛鉤,廣告引擎以及計費平臺等核心系統的穩(wěn)定性要求很高,可用性至少要做到3個9。
4、大數據存儲和計算:隨業(yè)務發(fā)展,推廣數量以及扣費訂單數量很容易達到千萬甚至上億規(guī)模,另外收入報表的聚合維度多,單報表可能達到百億級別的記錄數。
5、賬務的準確性:廣告扣費屬于金融性質的操作,需要做到不丟失、不重復,否則會損害某一方的利益。另外,如果收入數據不準確,還可能影響到業(yè)務決策。
了解了廣告業(yè)務的目標和技術挑戰(zhàn)后,接下來詳細介紹下廣告系統的整體架構和技術方案。

圖4:廣告系統的整體架構
上面是我們公司目前的廣告系統架構圖,這個架構適用于廣告業(yè)務初期,針對的是「自營型的競價網絡和站內流量」,不涉及聯盟廣告。
廣告投放系統:供廣告主使用,核心功能包括會員續(xù)費、廣告庫管理、設定推廣條件、設置廣告出價、查看投放效果等。
廣告運營后臺:供平臺的產品運營使用,核心功能包括廣告位管理、廣告策略管理、以及各種運營工具。
廣告檢索平臺:承接C端的高并發(fā)請求,負責從海量廣告庫中篩選出幾個或者幾十個廣告,實時性要求高,這個平臺通常由多個微服務組成。
AB實驗平臺:廣告業(yè)務的穩(wěn)定器,任何廣告策略上的調整均可以通過此平臺進行灰度實驗,觀察收入指標的變化。
廣告計費平臺:面向C端,負責實時扣費,和收入直接掛鉤,可用性要求高。
賬務管理中心:廣告業(yè)務中的財務系統,統管金額相關的業(yè)務,包括充值、凍結、扣費等。
大數據平臺:整個廣告系統的底盤,需要聚合各種異構數據源,完成離線和實時數據分析和統計,產出業(yè)務報表,生產模型特征等。
1. 廣告數據的存儲
廣告系統要存儲的數據多種多樣,特點各不相同,采用的是多模的數據存儲方式。

圖5:廣告數據的多模存儲
OLTP場景,包括廣告庫、創(chuàng)意庫、會員庫、廣告產品庫、廣告策略庫等,這些都存儲在MySQL中,數據規(guī)模較大的廣告庫和創(chuàng)意庫,按照廣告主ID Hash做分庫分表。 OLAP場景,涉及到非常多的報表,聚合維度多,單表的記錄數可能達到百億級別,底層采用HDFS和HBase存儲。
面向廣告檢索場景的索引數據,包括正排索引和倒排索引,采用Redis和ES來存儲。

圖6:廣告索引的更新流程
索引更新服務,有幾個要點說明下:
各個業(yè)務系統在推廣、余額等信息變更時,發(fā)MQ消息,索引更新服務訂閱MQ來感知變化,完成增量同步。
變更的消息體中,不傳遞實際變更的字段,僅通知有變化的廣告ID,索引更新服務實時讀取最新數據完成更新,這樣可以有效的解決消息亂序引起的數據不一致問題。
當更新索引的并發(fā)達到一定量級后,可通過合并相同廣告的變更、或者將倒排和正排更新分離的方式來提升整體的更新速度。
2. 廣告檢索平臺的整體流程
廣告檢索平臺負責承接C端的流量請求,從海量廣告庫中篩選出最合適的前N個廣告,并在幾十毫秒內返回結果,它是一個多級篩選和排序的過程。

Recall層側重算法模型,Search層側重業(yè)務。從下到上,計算復雜度逐層增加,候選集逐層減少。(說明:搜索廣告場景和推薦廣告場景在某些子模塊上存在差異,但整體流程基本一致,這里不作展開)
性能設計是檢索平臺的重點,通常有以下手段:
做好服務分層,各層均可水平擴展。
采用Redis緩存,避免高并發(fā)請求直接打到數據庫,緩存可按業(yè)務規(guī)劃多套,進行分流。
采用多線程并行化某些子流程,比如多路召回邏輯、多模型打分邏輯。
熱點數據進行本地緩存,比如廣告位的配置信息以及策略配置信息,在服務啟動時就可以預加載到本地,然后定時進行同步。
非核心流程設置超時熔斷走降級邏輯,比如溢價策略(不溢價只是少賺了,不影響廣告召回)。
和主流程無關的邏輯異步執(zhí)行,比如扣費信息緩存、召回結果緩存等。
精簡RPC返回結果或者Redis緩存對象的結構,去掉不必要的字段,減少IO數據包大小。
GC優(yōu)化,包括JVM堆內存的設置、垃圾收集器的選擇、GC頻次優(yōu)化和GC耗時優(yōu)化。
3. 計費平臺的技術方案

首先,整個扣費流程做了異步化處理,當收到實時扣費請求后,系統先將扣費時用到的信息緩存到Redis,然后發(fā)送MQ消息,這兩步完成后扣費動作就算結束了。
這樣做的好處是:能確??圪M接口的性能,同時利用MQ的可靠性投遞和重試機制確保整個扣費流程的最終一致性。
為了提高可用性,針對Redis和MQ不可用的情況均采用了降級方案。Redis不可用時,切換到TiKV進行持久化;MQ投遞失敗時,改成線程池異步處理。
另外,每次有效點擊都需要生成1條扣費訂單,面臨大數據量的存儲問題。目前我們采用的是MySQL分庫分表,后期會考慮使用HBase等分布式存儲。另外,訂單和賬務系統之間的數據一致性,采用大數據平臺做天級別的增量抽取,通過Hive任務完成對賬和監(jiān)控。

圖9:廣告數據倉庫的分層結構
源數據層:對應各種源數據,包括HDFS中實時采集的前后端日志,增量或者全量同步的MySQL業(yè)務數據表。
數據倉庫層:包含維度表和事實表,通常是對源數據進行清洗后的數據寬表,比如行為日志表、推廣寬表、用戶寬表等。
數據集市層:對數據進行輕粒度的匯總表,比如廣告效果表、用戶行為的全鏈路表、用戶群分析表等。
數據應用層:上層應用場景直接使用的數據表,包括多維分析生成的各種收入報表、Spark任務產出的算法模型特征和畫像數據等。
寫在最后
—?【 THE END 】— 本公眾號全部博文已整理成一個目錄,請在公眾號里回復「m」獲??! 3T技術資源大放送!包括但不限于:Java、C/C++,Linux,Python,大數據,人工智能等等。在公眾號內回復「1024」,即可免費獲取??!
