作者:謝健芬
Pinterest 廣告工程團隊的宗旨是為我們的廣告合作商提供最優(yōu)質(zhì)的服務(wù)體驗,而廣告超投,是我們極力要解決的問題之一。在Pinterest,我們使用了?Kafka Streams?,可以實現(xiàn)把廣告消耗的預(yù)測數(shù)據(jù)在數(shù)秒鐘的時間內(nèi)發(fā)送給數(shù)千個廣告投放服務(wù)。本文將會先解釋什么是超投,然后分享一下我們是如何使用 Kafka Streams 構(gòu)造預(yù)測系統(tǒng)來提供近實時的預(yù)測消耗數(shù)據(jù)、從而降低超投的。
關(guān)于超投
當廣告主的預(yù)算耗盡時,如果他們的廣告被繼續(xù)投放,這多出來的投放部分將無法再進行收費,這種現(xiàn)象被稱之為超投。超投會減少其他還有預(yù)算盈余的廣告主的廣告展現(xiàn)機會,從而降低了他們的產(chǎn)品和服務(wù)觸及潛在顧客的機會。
要降低超投率,應(yīng)從兩個方面著手:
計算實時消耗:廣告曝光展示的信息應(yīng)在數(shù)秒內(nèi)反饋給廣告系統(tǒng),系統(tǒng)才能及時關(guān)閉那些已耗盡預(yù)算的廣告計劃。進行消耗預(yù)測:除了讓已發(fā)生的消耗數(shù)據(jù)及時傳達以外,系統(tǒng)還應(yīng)具備預(yù)測未來消耗的能力,在預(yù)計某些計劃快要達到預(yù)算上限的時候,應(yīng)降低它們的投放速度,從而使計劃平滑地到達預(yù)算上限。因為已經(jīng)投放出去的廣告會停留在用戶界面上,用戶依然可以對它進行操作。這種行為的滯后性會讓短時間內(nèi)的廣告消耗難以準確地衡量。而這種自然延遲是不可避免的,我們唯一能確信的只有廣告投放事件。我們舉個例子來詳細說明一下。假設(shè)有一個能提供廣告投放的互聯(lián)網(wǎng)公司,廣告主X向該公司購買了出價為$0.10元/曝光?、預(yù)算為$100元/天的廣告服務(wù)。這意味著該廣告每天最多曝光1000次。
該公司為廣告主快速實現(xiàn)了一個簡單明了的投放系統(tǒng):
當網(wǎng)站上出現(xiàn)新的廣告展現(xiàn)機會時,前端會向廣告庫(ad inventory)請求一條廣告。廣告庫根據(jù)廣告主X的剩余預(yù)算來決定是否投放他們的廣告。如果預(yù)算仍然充足,廣告庫將通知前端進行一次廣告投放(比如在用戶端APP的一個廣告位上展示出來)。當用戶瀏覽了該廣告后,一個曝光事件會發(fā)往計費系統(tǒng)。
然而,當該公司檢查他們的收入時,發(fā)現(xiàn)事情的進展與預(yù)想的并不一樣。
廣告主X的廣告實際展示了1100次,由于預(yù)算只有$100,因此平均每次曝光的價格實際只有$0.09元。比計劃多出來的100次曝光相當于是免費投放了,而且這些曝光機會本來可以用來展示其他廣告主的廣告。這就是業(yè)界常談的超投問題。
那么為什么會發(fā)生超投?在這個例子中,我們假設(shè)是由于結(jié)算系統(tǒng)的響應(yīng)時間太長所導(dǎo)致的。假設(shè)系統(tǒng)對一次曝光的處理有5分鐘的延遲,從而導(dǎo)致了超投。因此,這個互聯(lián)網(wǎng)公司采取了一些優(yōu)化手段來提高了系統(tǒng)性能,結(jié)果成功地多賺了$9元!因為它把原本100次無效曝光中的90次讓給了其他預(yù)算充足的廣告主,從而把超投率降低到10/1000 = 1%。
不久之后,另一位廣告主Y也聯(lián)系了這家公司,并希望以$100元/天的預(yù)算、$2.0元/點擊(例如,一個用戶通過點擊廣告鏈接到達廣告主Y自己的網(wǎng)站)、最多每天50次點擊的價格購買廣告。這家公司把廣告主Y加到他們的廣告投放流程里,并在他們的系統(tǒng)增加了點擊事件的跟蹤。
一天下來,這家公司的廣告系統(tǒng)再次發(fā)生了超投。
結(jié)算下來,廣告主Y竟然得到了10個免費點擊!而這家互聯(lián)網(wǎng)公司發(fā)現(xiàn),即使結(jié)算系統(tǒng)處理速度足夠快,但卻無法預(yù)知一個投放出去的廣告是否會被點擊,由于缺乏這些未來的消耗信息,超投將永遠都無法避免。
本例子中的主人公最后找到了一個非常聰明的解決辦法:給每個廣告主計算預(yù)測消耗。預(yù)測消耗指的是已經(jīng)投放出去了但尚未發(fā)生消耗的那部分。如果實際消耗+預(yù)測消耗>每日預(yù)算,則停止該廣告主的廣告投放。
構(gòu)建預(yù)測系統(tǒng)
初衷
我們的用戶每天在Pinterest上進行瀏覽以獲取新的靈感:從個性化推薦,到搜索,再到運營推薦位。我們需要構(gòu)建一個兼具可靠性和可擴展性的廣告系統(tǒng)來進行廣告投放,并確保利用好我們廣告主的每一筆預(yù)算。
需求
我們著手設(shè)計了一個消耗預(yù)測系統(tǒng),系統(tǒng)目標如下:
能處理不同的廣告類型(曝光、點擊)必須具備每秒能處理數(shù)以萬計的事件的能力能向超過1000個消費者廣播更新消息端到端的延遲不能超過10秒保證100%的運行時間(Uptime)在工程上應(yīng)盡量保持輕量和可維護性為什么選擇Kafka Streams
我們評估過不同類型的流式服務(wù),其中也包括?Spark?和?Flink?。這些技術(shù)在數(shù)據(jù)規(guī)模上都能滿足我們的要求,但對我們來說,Kafka Streams還具備了一些特殊的優(yōu)勢:
毫秒級延遲:Kafka Streams提供毫秒級的延遲保證,這一點是Spark和Flink做不到的輕量:Kafka Streams是一個沒有重度外部依賴(比如專用集群)的Java應(yīng)用,這會減輕我們的維護成本。具體實施
下圖在高層次上展示了加入了消耗預(yù)測之后的系統(tǒng)結(jié)構(gòu):
廣告投放系統(tǒng)(Ads serving):負責(zé)分發(fā)廣告到用戶端、記錄廣告投放、并從消耗預(yù)測服務(wù)(”inflight spend” service)中獲取預(yù)測消耗數(shù)據(jù)。結(jié)算系統(tǒng)(Spend system):對廣告事件進行聚合并把每個廣告主的當前消耗信息告知給廣告投放系統(tǒng)。消耗預(yù)測服務(wù)(Inflight spend):廣告投放記錄(Ad insertion input):每發(fā)生一次投放,投放系統(tǒng)應(yīng)向“input” topic發(fā)送如下消息:{key: adgroupId, value: inflight_spend},其中:adgroupId是指在相同的預(yù)算約束下的廣告組的idinflight_spend = price * impression_rate * action_rate,其中:price: 當前廣告的出價impression_rate:廣告從投放到曝光的轉(zhuǎn)化率的歷史經(jīng)驗值。注意并不是每次投放的廣告都一定能被曝光給用戶action_rate:對按點擊付費的廣告主來說,這表示用戶點擊這條廣告的概率;對按曝光付費的廣告主來說,這個值為1消耗聚合器(spend aggregator):訂閱 “input” topic 并利用Kafka Streams對每個 adgroup 進行消耗數(shù)據(jù)的聚合。我們使用了一個10秒的窗口(window) 來計算每個 adgroup 的預(yù)測消耗。而“output” topic會被投放系統(tǒng)進行消費,當收到新的消息時,投放系統(tǒng)會更新預(yù)測消耗的數(shù)據(jù)。在實際應(yīng)用中,我們的消耗預(yù)測的準確率非常高。在整個預(yù)算預(yù)測系統(tǒng)上線之后,我們的超投率明顯下降了。下圖是我們的實際消耗與預(yù)測消耗的一個對比測試結(jié)果樣例。
說明:圖中的橫軸是以3分鐘為單位的時間軸;縱軸表示單位時間內(nèi)的消耗。其中藍線表示預(yù)測消耗,綠線表示實際消耗
一些經(jīng)驗
窗口(Window)如果取得不好會嚴重影響性能。我們在使?jié)L動窗口(tumbling ?windows)代替原有的跳躍窗口(hopping windows)后得到了18倍的性能提升。最初我們的實現(xiàn)是使用跳躍窗口去計算3分鐘內(nèi)的預(yù)測消耗。在我們的實際案例中,一個窗口的大小是3分鐘,前進步長是10秒,這樣就會產(chǎn)生180秒 / 10秒 = 18個開放窗口。每一個通過Kafka Streams處理的事件會同時更新到18個窗口中,導(dǎo)致很多不必要的計算。為了解決這個問題,我們把跳躍窗口改成了滾動窗口。相比起跳躍窗口,滾動窗口的特點是每個窗口之間不會互相重疊,意味著每收到一個事件只需要更新一個窗口就可以了。因為把更新操作從18減到了1,因此這個窗口類型更換的操作使整體吞吐量增加了18倍。信息壓縮策略:為了降低對消費者廣播的數(shù)據(jù)量,我們對 adgroup ID進行了差分編碼,并使用查找表存儲消耗數(shù)據(jù)。經(jīng)過壓縮后,我們把信息傳輸大小壓縮到原有的四分之一。結(jié)論
使用Apache Kafka Streams來構(gòu)建預(yù)測消耗系統(tǒng)是我們廣告基礎(chǔ)組件的一個新的嘗試,而該系統(tǒng)也達到了高效、穩(wěn)定、高容錯與可擴展的要求。我們計劃在未來將會持續(xù)探索由Confluent推出的?Kafka 1.0?和?KSQL?并應(yīng)用到系統(tǒng)設(shè)計上。
- 消息稱去年全球IT支出超過5萬億美元 數(shù)據(jù)中心系統(tǒng)支出大幅增加
- 2025年全球數(shù)據(jù)中心:數(shù)字基礎(chǔ)設(shè)施的演變
- 谷歌押注多模態(tài)AI,BigQuery湖倉一體是核心支柱
- 數(shù)字化轉(zhuǎn)型支出將飆升:到2027年將達到4萬億美元
- 量子與人工智能:數(shù)字化轉(zhuǎn)型的力量倍增器
- 華為OceanStor Dorado全閃存存儲榮獲CC認證存儲設(shè)備最高認證級別證書
- 2024年終盤點 | 華為攜手伙伴共筑鯤鵬生態(tài),openEuler與openGauss雙星閃耀
- 特朗普宣布200億美元投資計劃,在美國多地建設(shè)數(shù)據(jù)中心
- 工信部:“點、鏈、網(wǎng)、面”體系化推進算力網(wǎng)絡(luò)工作 持續(xù)提升算網(wǎng)綜合供給能力
- 2025年超融合基礎(chǔ)設(shè)施的4大趨勢
免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準確性及可靠性,但不保證有關(guān)資料的準確性及可靠性,讀者在使用前請進一步核實,并對任何自主決定的行為負責(zé)。本網(wǎng)站對有關(guān)資料所引致的錯誤、不確或遺漏,概不負任何法律責(zé)任。任何單位或個人認為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識產(chǎn)權(quán)或存在不實內(nèi)容時,應(yīng)及時向本網(wǎng)站提出書面權(quán)利通知或不實情況說明,并提供身份證明、權(quán)屬證明及詳細侵權(quán)或不實情況證明。本網(wǎng)站在收到上述法律文件后,將會依法盡快聯(lián)系相關(guān)文章源頭核實,溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。