Twitter廣告之“道”

來源:知乎
作者: 經(jīng)濟系程序員
時間:2020-08-18
3148
Twitter完成了廣告平臺的重構,并用博文Accelerating ad product development at Twitter記錄了這一過程,對從事AdServer工作的我很有啟發(fā)。我根據(jù)自己有限的知識,對全文進行了翻譯,并在局部進行了重寫。

譯者的話

我是酥酥,目前在Tubi用Akka和Scala搭建AdServer,此前在Twitter做廣告API的開發(fā)。我在從經(jīng)濟系畢業(yè)生到硅谷程序員一文中提到,在我離開Twitter前,Twitter的廣告平臺組剛開始風風火火地對AdServer進行微服務化重構,項目名稱Project Tao(道)。如今一年多過去,Twitter完成了廣告平臺的重構,并用博文Accelerating ad product development at Twitter記錄了這一過程,對從事AdServer工作的我很有啟發(fā)。我根據(jù)自己有限的知識,對全文進行了翻譯,并在局部進行了重寫。

康威定律指出,"組織的架構決定系統(tǒng)的架構"。Twitter廣告團隊也不例外。2010年,廣告團隊有約15名工程師和2800萬美元的收入,到了2019年,團隊增長至數(shù)百名工程師,有約34億美元的收入。期間,Twitter廣告系統(tǒng)的功能和復雜性一直在增加,而團隊或服務的運營模式并沒有大幅改變。

團隊早期的系統(tǒng)架構很適合初創(chuàng)公司,有利于拋下之前的決策包袱,快速迭代。廣告后端大致分為三個團隊。平臺(Platform)、科學(Science)和產(chǎn)品(Product)。團隊的最終目標是:快速構建和迭代廣告產(chǎn)品,幫助Twitter實現(xiàn)盈利。

Twitter的廣告平臺由基礎設施和核心組件構成,其中核心組件又包括AdServer、計費(billing)、數(shù)據(jù)基礎設施、分析(analytics)等系統(tǒng)。其中,單體AdServer(Monolithic AdServer)是廣告平臺的核心服務。它從Twitter客戶端獲取廣告請求,根據(jù)用戶信息和廣告主的定向(targeting)條件,對廣告池里的候選廣告進行排名,篩選出最符合條件的廣告,然后進行次價拍賣(second price auction),最后為用戶發(fā)送最相關的廣告作為響應。

團隊分工方面,平臺團隊負責搭建可靠、高性能的單體AdServer,并承擔部署和oncall的責任。產(chǎn)品團隊的重點則是根據(jù)Twitter前端產(chǎn)品團隊提的需求,在AdServer上做改動。本質上,平臺團隊扮演一個把關的角色,對改動和服務進行全面的控制。產(chǎn)品團隊則在平臺團隊的把關下,在代碼庫的各處做改動。

基于這種模式,Twitter打造了多款成功的廣告產(chǎn)品,它們的目標各不相同,復雜度越來越高。Promoted Tweets(推廣推文)首先推出,它幫助品牌覆蓋廣大的受眾,以提高品牌產(chǎn)品的知名度。Promoted Trend(推廣趨勢,類似于微博熱搜)使得品牌能夠占用全部Twitter用戶的探索欄全天的時間。Mobile App Promotion(移動app推廣)鼓勵用戶下載廣告主所要推廣的手機app。Web Clicks(網(wǎng)頁點擊)鼓勵用戶訪問品牌網(wǎng)站。Promoted Video(推廣視頻)讓品牌通過視頻這種更容易講故事的媒介來做推廣,還支持對廣告覆蓋面和效果的衡量。

這種模式在小規(guī)模的工程師團隊中效果非常好,迭代速度很快。但隨著業(yè)務和團隊的增長,平臺團隊開始成為功能迭代的瓶頸。為了更好地說明這一點,下面首先概述一個廣告請求的流程。

廣告請求的工作流

為了提供最相關的廣告,我們在廣告請求路徑中使用以下兩個組件:Ad Mixer和單體AdServer。

Ad Mixer是ad serving管道的網(wǎng)關(gateway)服務。每當收到一個來自客戶端的廣告請求,它都會:

·將請求轉發(fā)給單體AdServer,并接收來自AdServer的候選廣告響應。

·執(zhí)行次價拍賣,根據(jù)拍賣結果決定將要展示的廣告。

·儲存被展示的廣告的信息,根據(jù)用戶與廣告的交互行為,向廣告商收費。(譯者注:例如,如果用戶瀏覽了廣告,Twitter向廣告商收取x元。如果用戶瀏覽并下載了被推廣的app,Twitter可能向廣告商收取x+y元。)

單體AdServer負責對于每一個請求,考慮每一個符合條件的廣告,并將最佳的候選廣告返回給AdMixer??紤]到Twitter廣告產(chǎn)品的規(guī)模,該服務是分片(sharded)的,這樣每個分片只考慮全部候選廣告的一個子集。這種分片方案還使并行計算成為可能,滿足對廣告請求延遲的嚴格要求(要求在200-500毫秒不等)。

v2-7b3aec78f8862eafab05647f437d5046_720w.jpg

譯者注:拆分前,廣告請求的工作流。

譯者注:在此需要簡單了解廣告的三級結構:廣告組/campaign-廣告計劃/line item-廣告創(chuàng)意/creative。一個廣告組對應一到多個廣告計劃,一個廣告計劃對應一到多個廣告創(chuàng)意。廣告組描述一次推廣,例如“Nike瑜伽裝備2020秋季推廣”。廣告計劃通常包含對目標群體的描述,如“男性推廣”、“女性推廣”和“兒童推廣”,分別對應于三個目標群體。廣告創(chuàng)意描述具體要展示的內容,可能是一段視頻、一張海報、或一段文字。

每個AdServer分片,都根據(jù)它的候選廣告子集,執(zhí)行以下步驟。

·候選廣告選擇。我們?yōu)橛脩籼蕹幌嚓P(不符合年齡、地區(qū)或興趣等)的廣告,篩選出符合條件的廣告計劃。(譯者注:例如,若請求來自一個女性用戶,則篩除有關“男性推廣”的廣告計劃。)

·廣告創(chuàng)意的擴展和產(chǎn)品邏輯。我們根據(jù)Twitter的產(chǎn)品規(guī)則(因產(chǎn)品種類而異),將每一個候選廣告計劃擴展為一組廣告創(chuàng)意,并根據(jù)產(chǎn)品規(guī)則作進一步的過濾。(譯者注:將候選廣告擴展為廣告創(chuàng)意的過程可能涉及實時競價,即Real-time bidding,指AdServer根據(jù)廣告計劃的定向信息和用戶信息,對廣告交易所等第三方進行競價請求,從第三方獲取動態(tài)報價及創(chuàng)意信息。)

·候選廣告排名(包括早期過濾)。我們在產(chǎn)品邏輯階段后,根據(jù)用戶點擊廣告的可能性(調用實時訓練的機器學習模型)、廣告商的競價信息和拍賣特征,對候選廣告進行評分和排名。

從2010年到2018年,AdServer的邏輯日漸復雜。結果是:

·每次部署有包含數(shù)百個改動;(譯者注:Twitter出于各項考慮,沒有使用持續(xù)部署的方式,因此一次部署包含很多改動)

·雖然平臺團隊管理著AdServer,但AdServer的主要改動卻是來自產(chǎn)品團隊,導致兩個團隊“互為掣肘”。

此外,AdServer的幾個步驟之間沒有劃定明確的邊界,缺乏有效的機制來確保屬于"廣告創(chuàng)意的擴展和產(chǎn)品邏輯"的代碼不被加入到"候選廣告選擇"或"候選廣告排名"中。不清晰的邊界還給產(chǎn)品團隊的工程師(譯者注:以下簡稱產(chǎn)品工程師)帶來了額外的復雜性:單體AdServer本就是一個黑盒子,組件間強耦合,缺了哪一塊,AdServer都無法正常工作。產(chǎn)品工程師只了解AdServer的局部,很難測試。有時,一個很簡單的改動從開始開發(fā)到部署至生產(chǎn)中需要一個月的時間。

v2-69169220f47f5652fe56d17e9c71c3c2_720w.jpg

譯者注:單體AdServer的邏輯復雜。

廣告產(chǎn)品功能的生命周期

在2018年,基于上述平臺團隊和產(chǎn)品團隊的結構,一個視頻廣告產(chǎn)品功能的生命周期如下:

v2-1f1946e1bf1792455b479102534c541b_720w.png

代碼考古

由于產(chǎn)品和平臺的耦合,業(yè)務邏輯和基礎架構組件之間缺乏清晰的API邊界,AdServer代碼的復雜度指數(shù)爆炸。產(chǎn)品工程師首先需要理解錯綜復雜的平臺組件和產(chǎn)品組件,并試圖弄清楚當前AdServer是怎樣工作的。

設計

隨后,產(chǎn)品工程師將明確:需要對系統(tǒng)進行哪些改動?這里的挑戰(zhàn)包括:產(chǎn)品工程師難以完全理解視頻產(chǎn)品的改動對運行在同一單片AdServer中的其他廣告產(chǎn)品的影響。此外,他們也很難估計改動對性能的影響。

咨詢平臺團隊

一旦設計準備就緒,產(chǎn)品團隊的下一步將是與平臺團隊對接,由平臺團隊負責提供指導和代碼審查。然而現(xiàn)實中,由于平臺團隊負責平臺,而產(chǎn)品團隊負責產(chǎn)品,兩個團隊的激勵并不總是一致的,這導致產(chǎn)品的很多請求被平臺爭論甚至駁回,兩個團隊都感到失望和沮喪。

發(fā)布

一旦代碼通過審查,被合并,產(chǎn)品團隊需要再次依靠平臺團隊進行部署。新功能的測試往往十分困難,有時一個部署要包括多達200個改動。此外,由于多個產(chǎn)品的邏輯運行在同一個強耦合的單體AdServer中,一個錯誤的改動可能阻塞整個部署,從而影響到其它產(chǎn)品團隊。最終的測試要到發(fā)布后才能完成,且需要不同團隊的參與,因此修復突發(fā)bug的時間難以預測。

解決方案

引入產(chǎn)品競價器,加速產(chǎn)品迭代

我們從多個方面解決這些問題。我們首先將服務于不同廣告產(chǎn)品的基礎設施組件分離出來(例如選擇服務Selection Service,排名服務Ranking Service等,更多信息見我們之前的博文)。此外,提高產(chǎn)品團隊迭代速度的關鍵在于引入產(chǎn)品競價器(Product Bidder),并確保不同產(chǎn)品的競價器共用一個框架,以保持乘法效應。(譯者注:將拆分后的AdServer命名為bidder,可能因為競價是AdServer的一個重要環(huán)節(jié),不同產(chǎn)品之間的競價邏輯可能差異較大。)

v2-c281cb57441fcf102be9f14665e913d7_720w.jpg

譯者注:拆分后,廣告請求的工作流。

將單體服務的每個模塊都拆分為一個微服務看似會大大提高產(chǎn)品迭代效率,但這也使得跨服務改動經(jīng)常發(fā)生,降低開發(fā)效率。因此,在拆分過程中,我們做了適當?shù)娜∩幔?/span>

1.將單體AdServer拆分成不同的"產(chǎn)品競價器"服務,負責返回每個產(chǎn)品品種的"最佳"廣告。例如,視頻競價器只負責返回最佳的視頻廣告,手機app推廣競價器只負責返回最好的手機app推廣廣告。因此,每個競價器可以有自己的部署節(jié)奏、oncall、性能和運營特點。

2.將AdServer代碼庫拆分成競價器框架和產(chǎn)品專用邏輯,每個競價器的實現(xiàn)是競價器框架和產(chǎn)品邏輯的可配置組合。

v2-4835525185fe233b20752d3d24f02638_720w.jpg

譯者注:拆分后的AdServer流水線。

競價器框架

如上圖所示,每個管道(pipeline)都包含F(xiàn)ilter和Enricher等多個步驟。競價器框架規(guī)定了這條流水線的結構和執(zhí)行機制,而每個產(chǎn)品競價器可以根據(jù)具體產(chǎn)品需求做定制化執(zhí)行。

這種方法解耦了服務與產(chǎn)品,從而使平臺團隊只負責競價器框架,產(chǎn)品團隊負責競價器的具體實現(xiàn)。它最大程度地提高了開發(fā)的敏捷性和速度,同時保留了乘數(shù)效應。例如,框架升級會同時作用于所有產(chǎn)品競價器;所有產(chǎn)品競價器還能共享一套分析數(shù)據(jù)采集機制。

不同產(chǎn)品競價器之間的相互獨立,使得工程師可以對特定產(chǎn)品(如視頻廣告)進行更改,而完全不影響與視頻廣告不相關的產(chǎn)品。例如,如果一個新的視頻功能需要額外的計算資源,視頻產(chǎn)品競價器可以增大其允許延時,而不改變其它廣告產(chǎn)品的行為。

數(shù)據(jù)依賴框架

(譯者注:本段大量根據(jù)自己的理解寫成,可能與原文有出入)在AdServer的整條流水線中,每個步驟都涉及對通用數(shù)據(jù)結構的直接改動,這使得我們很難找出數(shù)據(jù)具體是在哪一個步驟被修改的。我們開發(fā)了一套數(shù)據(jù)依賴框架,嚴格規(guī)定了每個步驟的輸入輸出格式,禁止對通用數(shù)據(jù)結構的直接改動,而需要通過immutable的方式做改動,這樣能使每個步驟的職責更為清晰。

分片服務的數(shù)據(jù)獲取與傳輸

v2-976afd0270245130fae59b7d079b70dc_720w.jpg

譯者注:在Ad Mixer處進行數(shù)據(jù)抓取。

在原有系統(tǒng)中,Ad Mixer在每次廣告請求中,都會一次性獲取所需數(shù)據(jù)(比如用戶的個人信息、興趣、活動等),并將數(shù)據(jù)傳遞給各個分片AdServer。在拆分后,每個競價器需要不同的數(shù)據(jù)源,然而我們希望避免每個拆分的服務都各自進行數(shù)據(jù)獲取,因為這可能會使數(shù)據(jù)的獲取量增加400倍。我們選擇仍然在Ad Mixer處做一次性數(shù)據(jù)獲取,并使用以下方法確保競價器高效地獲取各自所需數(shù)據(jù):

1.對于不需要類型檢查的數(shù)據(jù),我們實現(xiàn)了直通(passthrough),中間服務只負責將原始字節(jié)傳輸?shù)街付ǖ南掠畏?,而不需要知道?shù)據(jù)的格式和內容。(譯者注:直通避免了序列化,降低數(shù)據(jù)傳輸成本。)

2.對于需要進行類型檢查的數(shù)據(jù),我們對其進行分類,并標記它們的消費者,以避免泄漏封裝,并確保下游服務不會錯誤地使用數(shù)據(jù)。(譯者注:若將某數(shù)據(jù)的消費者標記為視頻廣告競價器,則手機app推廣廣告競價器的邏輯將不會消費該數(shù)據(jù)。)

挑戰(zhàn)與經(jīng)驗

可靠的逐步遷移

在我們進行拆分之前,Twitter的單體AdServer上運行著價值30億美元的廣告業(yè)務。因此,在做拆分的同時,我們必須保持現(xiàn)有業(yè)務的運行,以及支持正在進行的產(chǎn)品開發(fā)。

在項目過程中,我們進行了廣泛的A/B實驗,由新系統(tǒng)支持小部分流量,由原有系統(tǒng)支持大部分流量,對產(chǎn)品指標進行詳盡分析,確保兩個系統(tǒng)在收入和各項指標上都基本符合,希望在不影響正常廣告業(yè)務的前提下,及早發(fā)現(xiàn)問題。

我們在長達4周的時間內,逐漸地給新系統(tǒng)增加流量比例。此外,我們還為每個產(chǎn)品競價器部署了約20%額外的容量,并啟用了保證30秒內完成回滾的機制。最后,我們在長達一個季度的時間內,將小比例的流量運行在之前的單體AdServer上,用于研究季節(jié)性對各項指標的影響。

代碼復雜度

拆分無可避免地需要直面非常復雜的遠古代碼,我們要搞清楚這些好幾年沒人碰過的代碼到底在做什么。我們努力將數(shù)據(jù)處理邏輯歸類到“候選廣告選擇”、“候選廣告排名”等核心組件,或是“預算計算”、“頻率管理”等小組件中。在技術債的泥潭中,做這些改動并不簡單。

揭露潛藏的bug

過去的八年中,團隊一直對AdServer做漸進性的改動,這樣做的缺點是難以發(fā)現(xiàn)大bug。這次拆分對系統(tǒng)做根本性的改變,幫我們發(fā)現(xiàn)了軟件中潛藏的bug。發(fā)現(xiàn)、診斷并修復這些bug花了我們一個季度的時間,但這使我們的系統(tǒng)更為健康。

權衡取舍

任何解決方案都不是萬能的,我們的團隊充分認識到這個決定的風險和收益,做出以下的“舍”:

失去對候選廣告做全局排名的能力

當我們將單體AdServer垂直拆分為多個產(chǎn)品競價器時,每個產(chǎn)品競價器都會分別給候選廣告排名。從而,我們失去了在AdServe內以接近全局的方式對所有候選廣告進行排名的能力。我們清楚利弊,決定通過增加最終拍賣所考慮的候選廣告的數(shù)量來彌補局部決策帶來的損失,以確保我們不會過濾掉原本有資格的候選廣告。(譯者注:假設有兩種廣告產(chǎn)品,視頻廣告和卡片廣告,二者分別有10個候選廣告。假定全局最優(yōu)的5個廣告中,有4個視頻廣告和1個卡片廣告。那么,如果我們在局部排名中,分別對視頻廣告和卡片廣告取前3名,匯總后再進行全局排名,則我們錯誤地過濾掉了一條視頻廣告。Twitter可能通過對二者各取前5名的方式來減少這種情況的發(fā)生。)

下游服務的流量增大

考慮到AdServer的規(guī)模,我們必選在項目開始時就估計好服務的流量情況,并提前6個月告知基礎設施團隊。我們使用一些原型(prototype)以及大量的壓力測試來確保估計的準確。

從單體AdServer改為多產(chǎn)品競價器架構后,AdServer對直接下游服務的請求數(shù)量增加,進而增加所有下游服務的壓力和成本??紤]到這一點,我們謹慎地選擇了要分割的產(chǎn)品垂直領域,以使我們獲得最大的投資回報。

發(fā)布平臺改動的發(fā)布周期變長

把AdServer按產(chǎn)品切分還意味著每一個平臺層面的改動都要在所有產(chǎn)品上完成測試和發(fā)布。我們清楚認識到、并且愿意承擔這個成本。

哪怕有上述不足,在競價器架構正式上線后,我們還是看到了產(chǎn)品隔離的好處。一個具體的例子是,我們通過給Promoted Trend競價器中的選擇服務配置一個緩存,實現(xiàn)延遲的降低,而完全不影響其它產(chǎn)品的行為。我們還看到產(chǎn)品功能的迭代不再被平臺團隊所阻塞,解決了一個主要的痛點。

總結

所有定律都有局限性,康威定律也不例外。它適用于所有的組織,但我們也可以共同努力打破它,確保服務和組織都適合未來的需求,而不是受制于歷史。切分并不能解決所有問題,但對團隊以及服務確實有積極的影響,其結果是產(chǎn)品工程師在新架構中添加新功能的工作流程得到了簡化。當我們開始這個項目的時候,這似乎是一個幾乎不可能完成的任務,但回過頭來看,它不僅幫助我們搭建了更健康的系統(tǒng),還加深了對系統(tǒng)工作方式的理解,為實現(xiàn)Twitter廣告部門的下一個宏偉目標奠定了基礎。

立即登錄,閱讀全文
原文鏈接:點擊前往 >
版權說明:本文內容來自于知乎,本站不擁有所有權,不承擔相關法律責任。文章內容系作者個人觀點,不代表快出海對觀點贊同或支持。如有侵權,請聯(lián)系管理員(zzx@kchuhai.com)刪除!
優(yōu)質服務商推薦
更多
掃碼登錄
打開掃一掃, 關注公眾號后即可登錄/注冊
加載中
二維碼已失效 請重試
刷新
賬號登錄/注冊
小程序
快出海小程序
公眾號
快出海公眾號
商務合作
商務合作
投稿采訪
投稿采訪
出海管家
出海管家