Rta 廣告投放技術(shù)實(shí)現(xiàn)及 SaaS 化思考
RTA背景
RTA這種投放模式這兩年逐漸興起, 目前國內(nèi)主流的流量媒體方都推出該項(xiàng)能力。如騰訊/頭條在2020年正式對(duì)外推出該項(xiàng)服務(wù),以此來幫助客戶進(jìn)一步提升廣告的精準(zhǔn)投放效果。
RTA(全稱Real-Time API),實(shí)時(shí)API接口,是媒體和廣告主之間通信的一套接口服務(wù)。主要流程如下:
- 在開通后在每次媒體將廣告給用戶曝光前,媒體將通過RTA接口來詢問廣告主是否參與本次曝光(參競(jìng));
- 廣告主接受請(qǐng)求后結(jié)合自身的數(shù)據(jù)和策略信息返回是否進(jìn)行曝光(參競(jìng))以及進(jìn)一步的決策結(jié)果;
- 媒體結(jié)合廣告主的結(jié)果信息進(jìn)行優(yōu)選,最終提升廣告主的廣告投放效果。
RTA有很多業(yè)務(wù)上的價(jià)值,比如可以針對(duì)場(chǎng)景做個(gè)性化的優(yōu)選,也讓廣告主有了參與廣告曝光決策的機(jī)會(huì)。
對(duì)于大部分客戶來說自身的私有數(shù)據(jù)是非常珍貴的,RTA能很好的保護(hù)私有數(shù)據(jù)。通常情況下廣告主想進(jìn)行流量的篩選比如想圈定或者排除某一部分人群,常規(guī)做法是打包一些定向數(shù)據(jù)上傳給媒體的DMP平臺(tái)作為定向投放數(shù)據(jù)包。該方式下數(shù)據(jù)無法實(shí)時(shí)更新、而且操作繁瑣,最重要的是還會(huì)將廣告主的數(shù)據(jù)直接暴露給媒體方。很多時(shí)候,數(shù)據(jù)是一個(gè)公司非常重要的資產(chǎn)尤其對(duì)數(shù)據(jù)比較敏感的金融行業(yè),某些數(shù)據(jù)不方便提供出去,RTA能很好地解決該類問題。
RTA接入要求
雖然RTA業(yè)務(wù)價(jià)值很明顯,但媒體對(duì)可以接入RTA的廣告主設(shè)有不小的門檻,這里我們主要討論的是技術(shù)上的門檻。
因?yàn)橐M(jìn)行實(shí)時(shí)的參競(jìng),媒體要求廣告主方有一定的技術(shù)和數(shù)據(jù)能力,亦即面對(duì)高并發(fā)的流量時(shí)能快速作出決策進(jìn)行實(shí)時(shí)答復(fù)。下面列舉了頭條要求廣告主方必須達(dá)到的硬性技術(shù)指標(biāo):
- 接口響應(yīng)時(shí)間在60ms內(nèi)(包括網(wǎng)絡(luò)和處理時(shí)間)
- 超時(shí)率要低于2%
- 預(yù)計(jì)高點(diǎn)流量可達(dá)10w/s~12w/s
其他媒體比如騰訊、快手、百度等的要求類似,接口的響應(yīng)時(shí)間都要在60ms內(nèi),需要能支持高QPS。根據(jù)業(yè)務(wù)場(chǎng)景投放的不同,實(shí)際的流量上限會(huì)有所不同。但通常媒體方一側(cè)都設(shè)有超時(shí)率門檻,針對(duì)不達(dá)標(biāo)的情況媒體方會(huì)有降級(jí)和最終的清退機(jī)制(即關(guān)閉廣告主的RTA接入通道)
ToB RTA 的業(yè)務(wù)場(chǎng)景
通過上面對(duì)RTA背景的了解,知道了RTA在精準(zhǔn)營銷及私有數(shù)據(jù)不外泄方面有不錯(cuò)的表現(xiàn)。但是RTA的接入門檻比較高,對(duì)于一些體量較小的公司,大部分不具備技術(shù)接入的能力。而且對(duì)于和營銷SaaS平臺(tái)的合作,一般采用和SaaS服務(wù)提供商聯(lián)合建模的方式合作,對(duì)于私有數(shù)據(jù)并不是特別敏感。通常的實(shí)現(xiàn)方式是:
- 廣告主在營銷SaaS供應(yīng)商側(cè)上傳人群包,由SaaS供應(yīng)商提供人群分析及RTA接口實(shí)現(xiàn)。
- 廣告主在媒體側(cè)開通賬號(hào),設(shè)置競(jìng)價(jià)相關(guān)的信息。把SaaS供應(yīng)RTA接口作為一個(gè)策略進(jìn)行配置。
RTA實(shí)現(xiàn)
API接口數(shù)據(jù)交換格式是基于http-protobuf,騰訊/頭條 均采用該方式,protobuf序列化可以獲得不錯(cuò)的壓縮性價(jià)比,契約由媒體方提供,按照契約進(jìn)行開發(fā)提供接口服務(wù)。這個(gè)還是比較簡(jiǎn)單的。
數(shù)據(jù)存儲(chǔ)的選型
對(duì)于數(shù)據(jù)存儲(chǔ)的選型上,這種場(chǎng)景下其實(shí)純內(nèi)存的數(shù)據(jù)庫是最合適的,但是應(yīng)用實(shí)現(xiàn)也需要權(quán)衡。考慮到公司基建的完善程度,在Hbase,aerospike 中進(jìn)行選擇,首先Hbase是不行的,因?yàn)镠base 最壞的情況下可能會(huì)有秒級(jí)延遲。但是對(duì)于kv這種存儲(chǔ)類型,在v 比較小情況下,aerospike的磁盤利用率很低??紤]到使用云廠商提供的kv 數(shù)據(jù)庫,但是被安全進(jìn)行否決,數(shù)據(jù)安全高于一切啊!!!
最終,采用了自建redis cluster 作為數(shù)據(jù)存儲(chǔ)層。
應(yīng)用架構(gòu)實(shí)現(xiàn)原則
基于RTA高并發(fā)且實(shí)時(shí)的業(yè)務(wù)要求,我們?cè)谇捌诤桶踩?運(yùn)維/DBA/基礎(chǔ)組件的同學(xué)溝通,確保該并發(fā)的條件下我們的基礎(chǔ)設(shè)施可以有效地承載,同時(shí)在一些設(shè)施上面進(jìn)行有效的資源隔離,以防止RTA影響到其他業(yè)務(wù)。
綜合考量后,我們作出如下的選擇和主要設(shè)計(jì)原則:
- 機(jī)房隔離:由于公司大部分業(yè)務(wù)在杭州機(jī)房,為了保證有效隔離,RTA應(yīng)用部署在上海機(jī)房。
- 避免阻塞/耗時(shí)操作:可采用異步化手段;對(duì)于那些需要降低下游QPS的地方,可采用隊(duì)列、緩存、批量操作等手段來進(jìn)行優(yōu)化
- 超時(shí)降級(jí):對(duì)于部分請(qǐng)求可能產(chǎn)生毛刺,從而導(dǎo)致超時(shí)帶來的雪崩以及帶寬的阻塞,必須對(duì)超時(shí)請(qǐng)求進(jìn)行降級(jí)處理。
- 資源保護(hù)/細(xì)節(jié)優(yōu)化:比如跨系統(tǒng)邊界的調(diào)用、有風(fēng)險(xiǎn)的本地代碼塊等,都可當(dāng)成資源進(jìn)行保護(hù)并提供有效的降級(jí)機(jī)制.通過優(yōu)化代碼,通過方法內(nèi)聯(lián)降低調(diào)用成本。
系統(tǒng)視圖
主要有一下幾個(gè)服務(wù):
- rta-uig:前置接收請(qǐng)求,并對(duì)后端應(yīng)用做負(fù)載均衡。
- config:分布式配置中心,業(yè)務(wù)人員對(duì)每個(gè)RTA請(qǐng)求是否曝光(參競(jìng))制訂策略,數(shù)據(jù)變更通知。
- rtaapp:rta 核心服務(wù),緩存客戶配置信息,處理請(qǐng)求,返回參競(jìng)數(shù)據(jù)。
- data-trans:廣告主數(shù)據(jù)處理和定時(shí)將數(shù)據(jù)同步到redis cluster。
下面是API接口的主要處理流程:
為保證HTTP的線程不阻塞,盡可能優(yōu)先采用異步處理方式。而且API直接依賴的2個(gè)數(shù)據(jù)源是Redis和JVM內(nèi)存,這樣可以滿足實(shí)時(shí)性的要求。
網(wǎng)絡(luò)問題
我們上面提到接口的響應(yīng)時(shí)間要在60ms以內(nèi),因此網(wǎng)絡(luò)的問題影響很大。
事實(shí)上我們的時(shí)間大部分花費(fèi)在網(wǎng)絡(luò)上,距離的遠(yuǎn)近直接影響著網(wǎng)絡(luò)時(shí)延。以目前對(duì)接的一些媒體來看,在接口消耗時(shí)間上,北京到上海大概30ms左右,上海公有云到公司機(jī)房的專線大概要2ms。在上線后,當(dāng)媒體方請(qǐng)求量增大時(shí),由于網(wǎng)絡(luò)抖動(dòng)導(dǎo)致tcp重傳,從而導(dǎo)致帶寬被瞬間打滿,所有的請(qǐng)求都被拒絕,在更換更大帶寬的設(shè)備后,問題得到緩解,但是帶寬成本是非常昂貴的。后期希望和安全部門協(xié)商,看看能不能把數(shù)據(jù)的安全等級(jí)進(jìn)行分類,部分?jǐn)?shù)據(jù)可以上公有云,這樣可以將數(shù)據(jù)部署里媒體側(cè)機(jī)房更近的地方。
資源保護(hù)
對(duì)資源進(jìn)行保護(hù)和有效降級(jí)非常重要。保護(hù)點(diǎn)主要基于業(yè)務(wù)上考慮來確定,可以是任意的代碼片段,并盡可能提供降級(jí)手段,以保證我們的主業(yè)務(wù)不受影響。如果依賴的下游服務(wù)宕機(jī)或者GC的導(dǎo)致進(jìn)程暫停,必須對(duì)請(qǐng)求進(jìn)行超時(shí)降級(jí)。對(duì)應(yīng)海量請(qǐng)求的超時(shí)處理,可以借鑒時(shí)間輪的原理,把時(shí)間復(fù)雜度控制在O(1),大幅提升性能,具體可以參考我前面的文章。
RTA SaaS化的思考
隨著業(yè)務(wù)的發(fā)展,接入客戶的增多,產(chǎn)品SaaS化是一個(gè)趨勢(shì),SaaS化必然面臨著多租戶數(shù)據(jù)之間的隔離,數(shù)據(jù)量的快速增長,怎么來處理這些事情,降本增效,利用少量的資源做更多的事情,各種性能指標(biāo)也能達(dá)標(biāo),是一個(gè)值得思考的問題。
Redis 內(nèi)存方面
對(duì)于使用Redis存儲(chǔ)的業(yè)務(wù)數(shù)據(jù),結(jié)合業(yè)務(wù)上的數(shù)據(jù)特點(diǎn),可以使用hash/zset存儲(chǔ)結(jié)構(gòu),限制key 的數(shù)量長度,使用ziplist,省下了大部分內(nèi)存,節(jié)約了成本。采用二級(jí)編碼的方式。整體上采用hash存儲(chǔ)后,查詢100萬條耗時(shí),也僅僅增加了500毫秒不到。具體可以看我之前的文章。
在后面的需求中,要對(duì)曝光的設(shè)備做一些策略,限制媒體每個(gè)設(shè)備每日到達(dá)多少量后不再進(jìn)行曝光,這依賴于對(duì)設(shè)備進(jìn)行計(jì)數(shù)。后面會(huì)對(duì)接多個(gè)媒體,總設(shè)備曝光請(qǐng)求數(shù)據(jù)每日可能高達(dá)上百億次,預(yù)計(jì)每日會(huì)有數(shù)十億的去重設(shè)備量。結(jié)合業(yè)務(wù)上的的特點(diǎn),設(shè)計(jì)如下:
- 設(shè)備有并發(fā),所以一定要原子操作,只能選擇INCR命令(string、hash、zset)。
- 媒體設(shè)備分別計(jì)數(shù),每日每個(gè)媒體計(jì)數(shù)業(yè)務(wù)規(guī)則上有上限(每日10次以內(nèi))。這意味著每個(gè)計(jì)數(shù)器可能達(dá)到的最大計(jì)數(shù)值是確定的,亦即計(jì)數(shù)器所需的位數(shù)是有限的、固定的。
例如Redis中對(duì)于整數(shù)類型采用的內(nèi)部編碼是int編碼,對(duì)應(yīng)Java里的long類型,占8個(gè)字節(jié)??梢詫⒁粋€(gè)8字節(jié)拆開,取合適的bit數(shù)量作為某個(gè)媒體計(jì)數(shù),結(jié)合hash存儲(chǔ)后還可以獲得數(shù)倍的空間節(jié)省。
熱點(diǎn)數(shù)據(jù)的優(yōu)化
由于業(yè)務(wù)上的特點(diǎn),我們會(huì)面臨大量的數(shù)據(jù)存儲(chǔ)需求,業(yè)務(wù)上一個(gè)很小的規(guī)則可能會(huì)使用很大的存儲(chǔ)資源。這要求我們謹(jǐn)慎設(shè)計(jì)數(shù)據(jù)存儲(chǔ),尋找有效的存取結(jié)構(gòu)。
業(yè)務(wù)上用的數(shù)據(jù),可以歸結(jié)為如下2類存儲(chǔ):
- JVM本地存儲(chǔ):系統(tǒng)業(yè)務(wù)配置、業(yè)務(wù)規(guī)則策略、業(yè)務(wù)的控制信息、熱KEY和黑名單等
- Redis存儲(chǔ):策略計(jì)算需要很多不同的數(shù)據(jù),數(shù)據(jù)量比較大,每份數(shù)據(jù)以億計(jì)
對(duì)于JVM本地存儲(chǔ),以對(duì)熱key的處理為例進(jìn)行說明。熱key是指同一個(gè)設(shè)備號(hào)的曝光請(qǐng)求被媒體反復(fù)下發(fā)。在業(yè)務(wù)上線的初期,我們發(fā)現(xiàn)很多設(shè)備請(qǐng)求被下發(fā)很多次,有的每日可達(dá)上千萬次,浪費(fèi)了處理資源,需要某種策略進(jìn)行應(yīng)對(duì)。為此,我們?cè)O(shè)計(jì)了收集反饋的方式,具體流程:API實(shí)例本地LFU隊(duì)列【LFU(Least Frequently Used) 算法根據(jù)數(shù)據(jù)的歷史訪問頻率來淘汰數(shù)據(jù),其核心思想是“如果數(shù)據(jù)過去被訪問多次,那么將來被訪問的頻率也更高”?!渴占?-> 上報(bào) -> 統(tǒng)計(jì) -> 反饋到API實(shí)例,如下圖所示:
總結(jié)
RAT已經(jīng)正常運(yùn)行了一段時(shí)間,在運(yùn)行中也發(fā)現(xiàn)了一些問題,目前來看系統(tǒng)運(yùn)行比較穩(wěn)定,等到模型效果驗(yàn)證后可以開始SaaS化演進(jìn),從這次項(xiàng)目推動(dòng)的過程中,可以發(fā)現(xiàn),應(yīng)用機(jī)房的選擇非常重要,數(shù)據(jù)部署最好和媒體側(cè)機(jī)房不要間隔太遠(yuǎn);接口的設(shè)計(jì)方面,盡量簡(jiǎn)約,對(duì)于不必要返回的字段和響應(yīng)頭,盡量去掉,節(jié)約帶寬(帶寬比較貴);數(shù)據(jù)存儲(chǔ)方面,使用內(nèi)存型數(shù)據(jù)庫,研究存儲(chǔ)類型的數(shù)據(jù)結(jié)構(gòu),利用合理的數(shù)據(jù)結(jié)構(gòu)節(jié)約存儲(chǔ)成本;做好接口超時(shí)降級(jí)處理,利用高效的超時(shí)判斷機(jī)制,盡量少的減少對(duì)應(yīng)用性能的損耗。
本文轉(zhuǎn)載自微信公眾號(hào)「小汪哥寫代碼」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系小汪哥寫代碼公眾號(hào)。