廣告引擎解析

來源:互聯網
上載者:User

標籤:

 

  • 廣告引擎
    • 總體設計
    • 檢索服務
      • 廣告檢索流程
      • 廣告定向
        • 定向維度下的選項很少,可以枚舉,這類定向包括,性別,年齡段,網路,系統。
        • 我們的系統現在是如何處理這類定向的
        • 定向維度有級聯關係,省,市,區
        • 定向維度是按照某個座標附近N公裡定向
      • 檢索服務是資料庫的副本
      • CTR計算
      • 計算二價
      • ADX廣告
    • 曝光服務
    • 計費服務
      • 計費服務主備
      • 浮點數問題
廣告引擎總體設計


我們的基本架構是用戶端請求API,然後由API發送RPC請求到我們的服務,服務通過註冊中心來管理
檢索服務,根據資料庫中的廣告建立索引,訂閱Redis Channel通過通知機制來使記憶體中的廣告與資料庫保持一致
曝光服務,接收曝光和點擊,彙總以後將彙總的結果推送到訊息佇列
計費服務,計費服務與支付系統進行互動,主要負責扣廣告主的錢,發起餘額不足,預算不足的下線

  • 下面先分服務單獨介紹
檢索服務廣告檢索流程

  • 參數解析,主要是為了過濾掉一些非法請求
  • 發起ADX廣告要求,這步首先對要向哪一家DSP發請求有個簡單的定向,然後再經過流量控制模組,確認可以發請求,會非同步發送HTTP請求,然後立刻返回,繼續下面的邏輯
  • 廣告定向,對自己的廣告按照定向進行初篩,得到所有合格廣告ID
  • 廣告過濾,根據一些邏輯規則,過濾掉不合格廣告ID
  • CTR計算,並按照ECPM排序,這部對所有廣告的所有素材計算點擊率,最後按照ECPM排序
  • 選擇各廣告位廣告,並計算二價
  • 與ADX廣告競價,之前非同步發送的廣告要求,在這裡需要等待每個請求的返回結果
  • 廣告內容格式化,按照不同類型的廣告格式化成用戶端的協議
  • 廣告曝光點擊參數加密,對一些資訊進行加密,尤其是這次廣告的曝光價格和點擊價格
廣告定向

需要解決的問題

一個使用者本身有一些屬性,比如性別,年齡,網路環境,裝置類型,地區資訊等等,而廣告主想讓自己的廣告投放在特定的人群中,根據使用者的屬性,檢索出可用的廣告過程就完成了廣告定向


比如這個例子,廣告2就不滿足定向條件,廣告3,廣告1滿足

定向維度下的選項很少,可以枚舉,這類定向包括,性別,年齡段,網路,系統。

廣告定向表

廣告ID 性別 年齡段 網路 作業系統
廣告1 不限 不限 不限 不限
廣告2 女 0-18 不限 不限
廣告3 男 0-18 不限 IOS

根據以上這張定向表,看上去有點像資料庫,假設圖中小人的流量來了,換成資料庫的查詢語句,應該是

where (性別=男 or 性別=不限)
and (年齡=0-18 or 年齡=不限)
and (網路=wifi or 網路=不限)
and (作業系統=ios or 作業系統=不限)

如果沒有“不限”,那麼看上去複合式索引是最好的選擇,我們把 性別-年齡-網路-作業系統 組合成一個索引,這樣索引的空間是

  • 2種性別 X 5段年齡 X 2種網路環境 X 2種作業系統 = 40種可能,每種可能對應一個ID的列表,為了用到複合式索引,必須把or語句去掉,可以把不限的廣告冗餘寫到所有的索引下,比如最極端的例子就是廣告1,所有都不限,那麼40種可能的組合下全部都有廣告1的冗餘
  • 我們的系統最開始就是這樣來檢索,好處就是只需要查詢一個索引就能取出定向的廣告,不好的地方也顯而易見就是會增加被索引資料的冗餘

where語句只看性別一個維度,or左右兩邊是等值查詢肯定可以利用索引求出兩個集合再取並集,然後再和其他維度取交集

  • 我們程式中也是類比這種先並再交的操作,資料中使用的btree來組織索引,我們程式中使用的是雜湊表,都是給定一個查詢的Key,返回一個被索引的內容

集合操作
如何取並集可以參考兩個有序數組的合并排序
如何取交集,一般有三種方法

  • 通用方法,選擇小集合作為base在大集合裡做二分尋找
  • 大集合交小集合,小集合如果可以放到記憶體可以使用把小集合在記憶體裡用構建hash索引,大集合作為base,在小集合裡雜湊尋找
  • 大集合交大集合,讓兩個都有序之後再交集M+N的複雜度,找到一個集合的最小,然後在另一個集合skip比這個數還小的所有資料
我們的系統現在是如何處理這類定向的

對每個維度在記憶體中建立倒排雜湊索引,然後我們把某個維度下的不限做了冗餘,這樣就不需要做並集,每個維度用資料最少的維度資料做為驅動表,然後在其他並集的結果中做雜湊檢測,如果不存在就把這個廣告刪除掉

注意,我們的定向只做了一次adid記憶體拷貝到某個流量檢索的上下文,而且拷貝的是最小的集合,其他要做的是不斷的雜湊檢測,把這個集合根據其他維度定向再縮小範圍

以上這種定向方法主要使用了倒排索引,還有一些求交集的技巧,倒排索引在處理等值查詢和動態多維度組合的時候是非常適合的,但是在處理範圍查詢的時候就不太好使了,比如我們年齡要是支援任意年齡區間的定向,也就是要處理範圍查詢,一些有序結構比如平衡樹會是更好的選擇

定向維度有級聯關係,省,市,區

廣告在地區定向條件如下

廣告地區定向表

廣告ID 省 市 區
廣告1 不限 不限 不限
廣告2 北京 北京市區 朝陽
廣告3 上海 上海市區 不限

假設一個使用者在北京,北京市區,朝陽要檢索廣告,SQL如下:

where (省=不限 and 市=不限 and 區=不限)
or (省=北京 and 市=北京市區 and 區=不限)
or (省=北京 and 市=北京市區 and 區=朝陽)

之前我們說可把不限這種情況冗餘到所有資料項目下面,這樣就避免了OR操作,省市區這種無法冗餘的原因有兩個

  • 一個是不知道冗餘到哪裡,因為省市區的選項有可能都不固定
  • 還有就是冗餘的話資料在定向是省市區都不限的時候冗餘量太大,要把全國每一個區縣都冗餘一遍

觀察這個SQL是先AND再OR,之前分析過多個AND適合複合式索引,所以假如我們可以把省-市-區看成一個索引中查詢的值,相當於我們查3次複合式索引,然後再取並集,得到的集合還需要和其他集合做交集,而且這個集合因為是OR出來的動態變化的所以不得不把廣告ID的列表拷貝出來,弄個暫存資料表。

如何最佳化暫存資料表,我想了兩種方法,但是目前還沒有做

  • 對暫存資料表緩衝固定查詢條件緩衝OR以後的暫存資料表
  • 根據集合運算定律A交(B 並 C) = (A交B) 並 (A交C),這樣把這個維度在最後運算可以首先保證A比較小,B,C是永遠不變的,做雜湊過濾就可以了。
定向維度是按照某個座標附近N公裡定向

首先座標可以轉成GEOHASH,然後N公裡可以再定向之後用過濾的方式計算
有幾點需要注意:

  • GEOHASH的精度,最小位應該能覆蓋附近N公裡,大概4位的GEOHASH可以覆蓋20KM,3位可以覆蓋78KM
  • GEOHASH因為只能定位一個大概,所以需要把廣告同時在附近的8個格子冗餘寫入廣告ID,這樣查詢的時候只需要查一個格子,不然就需要檢索9個格子
    總的來說這種方式就是簡單的在索引中做等值查詢where geo=abcd 做一次初篩,然後再過濾

 

過濾並不一定很慢,在資料庫中用索引反而更慢的例子,這個CASE最適合的是過濾
檢索服務是資料庫的副本

我們的檢索服務在啟動的時候會全量載入資料庫中的廣告,構建廣告的正排資料和倒排索引資料,多個副本通過訊息通知維護與資料庫的一致
通過訂閱redis的channel來擷取訊息,訊息類型包括,下線廣告主的廣告,同步推廣計劃,同步廣告,同步素材,重新全量載入資料
在重新載入資料的時候,線上服務還要繼續運行,所以我們使用了引用替換的方式,為了保證全量載入是有足夠記憶體,記憶體只能使用1/2
訊息機制有可能會不可靠,每個小時檢索服務與資料庫重新全量同步一次

  • 當記憶體中不足以裝下所有廣告的正倒排的時候,我們應該考慮的是兩反面,一個是壓縮儲存盡量裝載必要資訊,正排資料壓縮儲存;另一個是資料分區,比如按照地區分區,但是分區的時候還需要考慮到一些資料扭曲問題,目前我們還沒有碰到記憶體方面的平均。
CTR計算

每個廣告素材有一個CTR,所以CTR的計算量是很大的,我們的CTR計算採用非同步方式,當查詢一個廣告素材的CTR緩衝中沒有的時候,就返回預設CTR,然後非同步計算好這個素材的CTR填充到緩衝中

計算二價

計算方式 CPC廣告

  • first.clickPrice = second.ecpm / first.quality / first.ctr + 0.01 * 1000

CPM廣告

  • first.displayPrice = second.ecpm / first.quality 0.01
ADX廣告

面臨問題

ADX發送廣告要求是到外網,並且請求量大,在100ms以內返回,某一家DSP逾時不能對整體的廣告檢索有影響

我們針對這些問題做了如下幾方面的控制

  • 流量控制,針對每家DSP有QPS的控制
  • 使用NIO非同步發送請求
  • 長串連,盡量使用HTTP1.1的KEEPALIVE特性,不要讓第三方使用HTTPS的競價連結
  • 與每家DSP建立長串連的數量有最大值
  • 逾時率大於40%折半降低流量,直到設定的QPS最小值,當請求成功率大於40%倍增流量,直到達到當前這家DSP這隻的QPS值
  • 對逾時的控制,自己封裝了DspFuture使用HashwheelTimer定時器來控制逾時時間

針對ADX還需要加強的地方

  • 連結的預熱,可以預先對每家DSP建立好長串連以後再對外提供服務
  • 網路鏈路的選擇,與DSP之間的網路出現問題的時候,可以對某一家DSP嘗試使用不同的鏈路,或者優先使用最經濟的鏈路
曝光服務

接收到曝光點擊以後在記憶體中做彙總,每分鐘把彙總後資訊推送到訊息佇列

計費服務

計費服務從訊息佇列消費曝光服務彙總後的曝光點擊,其中曝光是每分鐘消費一次,點擊是即時消費。
曝光的消費是兩個線程協作,一個線程負責從訊息佇列拉資料然後彙總N台曝光服務推入的內容,一個線程負責消費。

  • 當消費線程發生阻塞的時候,計費服務如果把彙總後的曝光都儲存在記憶體中有遺失資料的風險,所以我們隊計費服務從訊息佇列中拉取訊息的速度做了控制,最多隻可以彙總幾分鐘的資料
計費服務主備

計費服務一主一備,通過redis實現租約
redis中有一個叫lock的key,value是當前工作節點的名字,有一個到期時間。
主服務,每秒鐘先get(lock),然後判斷是否與自己當前節點名字一致,如果一致的話,使用expire方法進行續約
備服務,每秒鐘嘗先嘗試寫lock這個key為自己節點的名稱,使用redis的setex方法,因為key已經存在,所以會返回false

浮點數問題

因為計費經驗做一些錢方面的檢查,所以涉及浮點數精度問題
浮點數做減法使用BigDecimal.subtract()方法
浮點數做乘法使用BigDecimal.multiply()方法
浮點數做除法使用BigDecimal.divide()方法

 

廣告引擎解析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.