Twitter重構(gòu)了廣告平臺,twitter有哪些廣告位Twitter重構(gòu)了廣告平臺軟件系統(tǒng)的一大優(yōu)點是它們具有極強的適應(yīng)性。然而,在復(fù)雜軟件系統(tǒng)的演進過程中,這種可塑性會阻礙而不是促進其發(fā)展。在某種程度上,軟件將進入一個不再服務(wù)于其目的——為人們提供幫助——的階段。這就是2019年初Twitter AdServer的......
軟件系統(tǒng)的一大優(yōu)點是它們具有極強的適應(yīng)性。然而,在復(fù)雜軟件系統(tǒng)的演進過程中,這種可塑性會阻礙而不是促進其發(fā)展。在某種程度上,軟件將進入一個不再服務(wù)于其目的——為人們提供幫助——的階段。
這就是2019年初Twitter AdServer的情況。經(jīng)過10年的迭代開發(fā)之后,系統(tǒng)的效率已經(jīng)太低,無法與組織的發(fā)展保持同步。剛開始的時候,我們是一個非常小的工程師團隊,只提供單一類型的廣告格式(推廣推文),創(chuàng)造了大約2800萬美元的收入。如今,Twitter的收入組織包括10倍以上的工程師和約30億美元的收入,支持多種廣告格式——品牌、視頻、卡片。
新產(chǎn)品發(fā)布慢,團隊之間緊密依賴,管理成本很高,這些都增加了組織的復(fù)雜性。為了進一步擴大規(guī)模,我們就得進行根本性的改革。
我們是如何投放廣告的
AdServer漏斗(funnel)主要由Admixer和Adshard組成。Admixer是上游客戶端和AdServer管道之間的接口。當Admixer收到一個廣告請求時,在將請求分發(fā)給Adshard之前,它會將額外的用戶信息補充到請求中。Adshard在分片架構(gòu)下運行,每個Adshard負責一個廣告子集,通過AdServer漏斗的3個主要階段運行請求:
·候選項選擇:為用戶選擇一組有效的活動子項(即一組具有相同目標市場選擇標準的廣告;有關(guān)詳細信息,請參考活動子項定義)。在這一階段,(1)我們應(yīng)用了所有標準的活動目標選擇條件,最終為用戶提供符合條件的廣告(例如地理位置、年齡、興趣等);(2)剔除用戶可能不喜歡的不相關(guān)的廣告;(3)確保我們只提供有效的廣告(例如,只提供沒有結(jié)束的活動)。
·產(chǎn)品邏輯:此階段根據(jù)一些業(yè)務(wù)規(guī)則將來自候選項選擇階段的每個活動子項擴展為一組創(chuàng)意,并添加額外的產(chǎn)品特性豐富這些創(chuàng)意。(創(chuàng)意是實際展示給用戶的廣告,例如一條推廣推文——請參考創(chuàng)意定義了解更多細節(jié))。
·候選項排名:完成上述階段后,對廣告進行排名。每個廣告都會得到一個分數(shù)(表示用戶瀏覽該廣告的可能性),并根據(jù)這個分數(shù)對廣告進行排名。我們使用一些實時訓(xùn)練的機器學(xué)習(xí)模型和廣告客戶數(shù)據(jù)來計算我們在競價管道中使用的分數(shù)。
在這個漏斗中,不同的組件還附加了與廣告請求和廣告候選相關(guān)聯(lián)的元數(shù)據(jù),并會將這些元數(shù)據(jù)寫入AdMixer中我們的底層鍵值存儲中。稍后,在反饋循環(huán)中,分析管道將使用這些數(shù)據(jù),用于賬單、欺詐檢測和其他分析。
過去,我們是通過盡可能減少網(wǎng)絡(luò)跳數(shù)來優(yōu)化系統(tǒng),以最小化延遲和操作開銷。這導(dǎo)致單個服務(wù)(即Adshard)完成了大部分繁重的工作,進而形成了一個單體模型。
熵增
當Twitter只有兩種廣告產(chǎn)品——推廣推文和推廣賬戶時,這個單體平臺運行得很好。然而,當我們擴大業(yè)務(wù)時,單體模式帶來的挑戰(zhàn)便多于解決方案了。
新增一個廣告產(chǎn)品
在舊的Adserver中,由于遺留代碼的挑戰(zhàn)和復(fù)雜性,重用現(xiàn)有模式和實踐就成了常態(tài)。上圖是一個在舊的AdServer上新增一個廣告產(chǎn)品(如推廣趨勢)的例子。該廣告產(chǎn)品具有以下特點:
1.應(yīng)該總是根據(jù)條件Geo==Country選取;
2.應(yīng)該不需要競價,從而可以跳過排名階段。
通常,新增一個廣告產(chǎn)品需要做一些零零碎碎的工作??紤]到現(xiàn)有框架的性質(zhì)和其他遺留代碼的約束,跳過排名階段不是可行的選項,于是我們采用了一種不合常規(guī)的變通方法,在排名管道里向代碼中添加基于產(chǎn)品的條件邏輯if(producttype==PROMOTEDTREND){...}else{..}。這種基于產(chǎn)品的邏輯也存在于選擇管道中,導(dǎo)致了這些階段緊密耦合,增加了日益增多的意大利面式代碼的復(fù)雜性。
開發(fā)速度
下面是所有基于大量的遺留代碼進行開發(fā)的團隊都面臨的一些挑戰(zhàn)。
·過度膨脹的數(shù)據(jù)結(jié)構(gòu):請求和響應(yīng)對象的大小隨著業(yè)務(wù)邏輯的增加而快速增長。由于請求/響應(yīng)對象在這3個階段中共享,所以不變性保證是一項挑戰(zhàn)。在候選排名階段添加一個新特性,需要了解該特性所需的字段在上游(選擇和創(chuàng)意階段)和下游(Admixer)是在何處如何設(shè)置的。要想修改的話,就幾乎需要了解整個服務(wù)管道。這是一個令人畏縮的過程,尤其是對新工程師來說。
·數(shù)據(jù)訪問挑戰(zhàn):從歷史上看,Admixer一直是負責獲取用戶相關(guān)數(shù)據(jù)的服務(wù),這主要是為了延遲和資源優(yōu)化。(由于采用分片架構(gòu),在Adshard中獲取相同的用戶數(shù)據(jù)需要25x RPC)。因此,要在Adshard中使用一個新屬性,我們需要在Admixer中添加相應(yīng)的用戶數(shù)據(jù)獲取器,并將其發(fā)快遞給Adshard。這個過程非常耗時,并且,取決于用戶屬性的類型,可能會對AdServer的性能產(chǎn)生影響。這個過程也使得解耦平臺與產(chǎn)品變得非常具有挑戰(zhàn)性。
·技術(shù)債務(wù):復(fù)雜的遺留代碼增加了技術(shù)債務(wù)。棄用舊字段以及清理未使用代碼的風(fēng)險越來越大。這通常會導(dǎo)致功能的意外更改,引入bug并拉低整體生產(chǎn)力。
解決方案:我們?nèi)绾卧O(shè)計這些服務(wù)
這些長期存在的工程問題以及開發(fā)人員的生產(chǎn)力損失,使得我們需要改變系統(tǒng)設(shè)計的范式。我們在架構(gòu)中缺乏明確的關(guān)注點分離,并且不同的產(chǎn)品領(lǐng)域之間高度耦合。
在軟件行業(yè)中,這些問題相當常見,而將單體分解成微服務(wù)是解決這些問題的流行方法。然而,它本身也是有利有弊,如果倉促設(shè)計,反而會導(dǎo)致生產(chǎn)率降低。讓我們通過一個例子看下分解服務(wù)時可能采用的一種方法。
服務(wù)分解思考練習(xí):每個產(chǎn)品一個AdServer
由于單體AdServer對每個產(chǎn)品團隊而言都是一個瓶頸,而不同的產(chǎn)品可能有不同的架構(gòu)需求,所以我們可以選擇將單個AdServer分解為N個不同的AdServer,每個產(chǎn)品一個,或者一組類似的產(chǎn)品一個。
在上面的架構(gòu)中,我們有三個不同的AdServer,分別用于Video Ad Product、Takeover Ad Product和Performance Ad Product。它們由各自的產(chǎn)品工程團隊負責,每個團隊都有自己的代碼庫和部署管道。這似乎提供了自主性,并有助于分離關(guān)注點,解耦不同的產(chǎn)品領(lǐng)域,然而,實際上,這樣的分離可能會使事情變得更糟。
現(xiàn)在,每個產(chǎn)品工程團隊都必須增加人手來維護整個AdServer。每個團隊都必須維護和運行自己的候選生成和候選排名管道,即使他們很少修改它們(這些通常是由機器學(xué)習(xí)領(lǐng)域?qū)<邑撠熜薷模?。對于這些領(lǐng)域,情況變得更糟?,F(xiàn)在,要發(fā)布一個用于廣告預(yù)測的新特性,我們需要修改三個不同服務(wù)的代碼,而不是一個最后,很難確保來自所有AdServer的分析數(shù)據(jù)和日志能夠融合到一起,以確保下游系統(tǒng)的正常運行(分析是跨產(chǎn)品的橫切關(guān)注點)。
經(jīng)驗總結(jié)
我們認識到,僅僅分解是不夠的。我們在上面為每個產(chǎn)品構(gòu)建的AdServer架構(gòu)既缺少內(nèi)聚性)(每個AdServer仍然做了太多的事情),也缺少可重用性(例如,在所有三個服務(wù)中都運行著的廣告候選排名)。我們突然認識到,如果我們要為產(chǎn)品工程團隊提供自主性,就必須用可以跨產(chǎn)品重用的橫向平臺組件來為他們提供支持為橫切關(guān)注點提供即插即用的服務(wù)可以為工程團隊創(chuàng)造乘數(shù)效應(yīng)。
我們構(gòu)建了橫向平臺組件
因此,我們確定了可以被大多數(shù)廣告產(chǎn)品直接使用的“通用廣告技術(shù)功能”,包括:
·候選項選擇:給定用戶屬性,確定可以針對用戶需求展開競逐的廣告候選項。
·候選項排名:給定用戶屬性和廣告候選項,根據(jù)與用戶的相關(guān)性給廣告候選項打分。
·回調(diào)和分析:定義契約,標準化所有提供廣告服務(wù)的服務(wù)的分析數(shù)據(jù)集。
我們圍繞這些功能構(gòu)建服務(wù),并將自己重組為平臺團隊,每個團隊擁有其中一個功能。以前架構(gòu)中的產(chǎn)品AdServer現(xiàn)在變成了更精簡的組件,它們依賴于橫向平臺組件,并在其上構(gòu)建特定于產(chǎn)品的邏輯。
好處
便于添加新產(chǎn)品
讓我們重新審視上面提到的與聚光燈廣告有關(guān)的問題,以及新架構(gòu)如何處理這個問題。通過構(gòu)建不同的廣告候選項選擇服務(wù)和廣告候選項排名服務(wù),我們可以更好地將關(guān)注點分離開來。它打破了廣告產(chǎn)品必須采用AdServer管道的3階段范式這一模式?,F(xiàn)在,聚光燈廣告有了靈活性,可以只與選擇服務(wù)集成,使得這些廣告可以跳過排名階段。這讓我們擺脫了為繞過推廣趨勢廣告排名而采用的笨拙方法,實現(xiàn)了一個更干凈、更健壯的代碼庫。
隨著廣告業(yè)務(wù)的持續(xù)增長,添加新產(chǎn)品將會很容易,只要在需要的時候引入這些橫向平臺服務(wù)就可以了。
提升速度
通過定義良好的API,我們可以在團隊之間實現(xiàn)職責分離。修改候選項排名管道不需要理解選擇或創(chuàng)意階段。這是一種雙贏的局面,每個團隊只需要理解和維護他們自己的代碼,這讓他們可以更快地采取行動。這也使得故障更加容易診斷,因為我們可以隔離服務(wù)中的問題并獨立地測試它們。
風(fēng)險與利弊
在Twitter,這種廣告模式的轉(zhuǎn)變必然會伴隨著風(fēng)險和權(quán)衡。我們想列出其中一些,以提醒讀者,在決定對現(xiàn)有系統(tǒng)進行大規(guī)模重構(gòu)之前,必須識別和承認存在的弊端。
·增加硬件成本:從一個服務(wù)創(chuàng)建許多不同的服務(wù)無疑意味著增加運行這些系統(tǒng)的計算成本。為了確保增長在可接受的范圍內(nèi),我們?yōu)樽约涸O(shè)定了一個具體目標,將廣告服務(wù)系統(tǒng)的運營成本控制在收入的5%以內(nèi)。這有助于我們在需要的時候優(yōu)先考慮效率,讓我們更容易做出設(shè)計決策。就計算資源而言,新架構(gòu)的開銷大約是前一個架構(gòu)的兩倍,但這在我們可以接受的限度之內(nèi)。
·增加了產(chǎn)品開發(fā)團隊的運營成本:擁有多個新服務(wù)意味著維護和運營這些服務(wù)的工程成本,其中一些新增的負擔落在了產(chǎn)品開發(fā)團隊身上(而不是像之前那樣更多地落在平臺團隊身上)。這意味著除了要加速開發(fā)新特性外,產(chǎn)品開發(fā)團隊還需要適當?shù)爻砷L以支持他們擁有的新系統(tǒng)。
·新特性開發(fā)的暫時放緩:這項工作需要花費超過40名工程師以及工程和產(chǎn)品經(jīng)理1.5年的時間。我們估計,在此期間,新特性的開發(fā)速度會降低大約15%(主要是在廣告服務(wù)方面)。為了支持這個項目,組織負責人會愿意做出這樣的權(quán)衡。
·競價排名的復(fù)雜性增加:這是對新架構(gòu)的技術(shù)考量——由于每個產(chǎn)品負責人都服務(wù)于自己的請求,我們部分失去了在更低粒度上對廣告排名和競價做出全局最優(yōu)決策的能力。通過將這種邏輯轉(zhuǎn)移到更高粒度的集中式平臺服務(wù)上,可以在某種程度上彌補這一點。
我們評估了這些風(fēng)險,并且確定,新架構(gòu)的好處大于這些風(fēng)險造成的影響。整體開發(fā)速度的提高和更可預(yù)測的特性改進交付,對于我們?yōu)樽约涸O(shè)定的雄心勃勃的業(yè)務(wù)目標至關(guān)重要。新架構(gòu)提供了一個模塊化系統(tǒng),讓我們可以更快的試驗,并降低了耦合度。
我們已經(jīng)開始看到這種決策的好處了:
·對于大多數(shù)規(guī)劃好的項目,沒有一個團隊會成為瓶頸,而在規(guī)劃好的廣告服務(wù)項目中,90%以上的都可以執(zhí)行。
·試驗速度快了許多——在廣告服務(wù)空間進行的在線排名試驗現(xiàn)在快了50%。
遷移
多個團隊每天都推快遞新代碼這樣一個部署節(jié)奏,再加上數(shù)十萬QPS的龐大規(guī)模,使得AdServer的分解非常具有挑戰(zhàn)性。
在開始遷移時,我們采用了內(nèi)存內(nèi)API優(yōu)先的方法,對代碼進行邏輯分離。另外,這還使我們能夠運行一些初始的系統(tǒng)性能分析,保證與舊系統(tǒng)相比,CPU和內(nèi)存占用的增量是可接受的。這奠定了橫向平臺服務(wù)的基礎(chǔ),這些基本服務(wù)源自重構(gòu)代碼并重新安排內(nèi)存版本的打包結(jié)構(gòu)。
為了確保新舊服務(wù)在功能上的一致性,我們開發(fā)了一個自定義的正確性評估框架。它分別針對舊AdServer和新AdServer重放了請求,以便在可接受的閾值內(nèi)比較兩個系統(tǒng)的指標。我們在離線測試中使用了這種方法,借此我們可以了解新系統(tǒng)的性能。它幫助我們及早發(fā)現(xiàn)問題,防止錯誤進入生產(chǎn)環(huán)境。
在將代碼發(fā)國際快遞生產(chǎn)環(huán)境后,我們使用了一個試驗框架,讓我們可以洞察生產(chǎn)環(huán)境中的總體收益指標。許多預(yù)測和競價相關(guān)的度量標準需要一個更長的反饋循環(huán)來消除噪音和評估變更的真實影響。因此,對于遷移的真正的端到端驗證,我們依賴這個框架來保證收入指標的正常。
總結(jié)
分解AdServer改善了我們系統(tǒng)的狀態(tài),強化了Twitter廣告業(yè)務(wù)的基礎(chǔ),讓我們可以把時間和資源集中在解決真正的工程問題上,而不是與遺留基礎(chǔ)設(shè)施的問題作斗爭。隨著廣告業(yè)務(wù)和技術(shù)的發(fā)展,更多的挑戰(zhàn)將會到來,但我們很高興能夠建立可以提高系統(tǒng)效率的解決方案。
英文原文:
https://blog.twitter.com/engineering/enus/topics/infrastructure/2020/buildingtwittersadplatformarchitectureforthefuture.html
作者TwitterEng
譯者平川
策劃Tina
特別聲明:以上文章內(nèi)容僅代表作者本人觀點,不代表ESG跨境電商觀點或立場。如有關(guān)于作品內(nèi)容、版權(quán)或其它問題請于作品發(fā)表后的30日內(nèi)與ESG跨境電商聯(lián)系。
二維碼加載中...
使用微信掃一掃登錄
使用賬號密碼登錄
平臺顧問
微信掃一掃
馬上聯(lián)系在線顧問
小程序
ESG跨境小程序
手機入駐更便捷
返回頂部