1. 程式人生 > >廣告效果資料的實時計算與分析(Druid)(一)

廣告效果資料的實時計算與分析(Druid)(一)

我是做SSP-供應方平臺服務的,工作中除了負責SSP 管理後臺的需求開發(如,媒體應用和位置的管理、流量分配、效果資料的報表展示、SDK效能分析等)之外,最主要的是負責SSP廣告效果資料的實時統計與分析,為媒體主及運營人員提供可靠的資料,方便其分析或查詢問題及時調整策略提高SSP的收入及為媒體提供高質量的廣告。

廣告平臺的基本概念介紹

廣告收入佔據這網際網路公司的大半收入,很多免費軟體、視屏播放器、音訊播放器、防毒軟體或者其他的APP等都是靠廣告來賺錢的,廣告的形式有多種,如開屏、插屏、橫幅、資訊流、視屏廣告等,廣告平臺根據面向的使用者或者是提供的功能不同又分為:DSP、ADX、SSP、DMP這個四個平臺,下面是這四個平臺的基本概念:
DSP-需求方平臺,也就是廣告主服務平臺,廣告主可以通過DSP平臺設定自己想要的受眾目標以及願意出多少錢購買這些受眾的曝光等操作完成廣告投放,面向廣告購買方。
SSP-供應方平臺,它是媒體服務平臺,媒體方可以通過SSP平臺完成廣告資源的管理,如流量分配、價格、篩選等等,面向廣告售賣方。
ADX-廣告交易平臺,連線買方和賣方,ADX將媒體的廣告流量以拍賣的方式賣給DSP。
DMP-資料管理平臺,整合各方資料並提供資料分析,資料管理、資料呼叫等,用來指導廣告主進行廣告優化和投放決策。

SSP廣告效果資料現有架構

廣告效果資料量是巨大的,從一天的一兩千萬的資料慢慢的增長到數十億,一天要處理幾十GB的資料,資料延時的在10分鐘,即當前時間能要能看到10分鐘之前的所有效果資料,這個對服務的可用和實時還是挺有壓力和挑戰的,目前有很多實時計算框架,如spark/storm 都具有這個能力,我們採用的是Spark Streaming+Metaq+Flume+Hadoop+Hive的架構實現廣告效果資料的準實時統計與分析。整個流程如下:
SDK向SSP服務端發情廣告請求,SSP在接收到SDK的請求後根據協議解析相關的請求引數,根據媒體的位置上配置的流量進行分配向不同的ADX傳送請求等待廣告的放回,在等到超時或者ADX返回了廣告後,拼裝廣告素材返回給SDK,並把該次請求廣告的位置及ADX返回的廣告填充等資訊通過傳送至Flume,然後Flume 集中廣告資料傳送沒Metaq 叢集,Spark Streaming 不停的消費Metaq中的訊息,並把原始資料儲存到Hive表中(方便後面做其他離線資料分析),然後讀取Hive中的資料根據規則進行分析與計算並把結果寫到MySql中進行報表展示。

該架構目前處理幾十GB的資料,還沒有看到瓶頸與壓力(一般會調整CPU數量及記憶體的大小來面對越來越多的資料),但是隨著結果資料的越來越多MySql中的資料量越來越大,達到幾千萬資料的時候查詢所需的時間,單單優化SQL優化索引是很難解決問題,此時就需要分庫分表,如根據應用或者時間等進行分表,但分庫分表的缺點也是很明顯的就是本來一條SQL能完成的事,分庫分表後需要更復雜的方案來實現同樣的功能、例如根據時間分組,一個月一張表,此時需要根據應用維度來分析資料(當然你也可以按應用分表來解決問題,這裡只是舉個例子)查詢應用的近兩個月的總的請求量,此時如果不分表:select sum(requestTime) ,appId from stat_table group by appId where stat_date>=xx and stat_date<=xx 就可以查詢出應用最近兩個月總的請求量,但是按時間分表後, 就需要執行這條sql 兩次從每個分表中查詢資料,然後還需要寫程式碼在記憶體中對相同的應用進行請求量相加聚合處理,這裡只是一個簡單的需求,面對千變萬化的需求處理起來還是有一定的難度的,業務實現也較為複雜。

Druid 實時分析系統的簡單介紹

Druid的目的是提供一個能夠在大資料集上做實時資料消費與探索的平臺,對普通的資料平臺來說,資料的高效攝入與快速查詢往往是一對難以兩全的指標,因此常常需要在其中做一些取捨與權衡。如傳統的關係型資料庫如果想要在查詢的時候有更快的響應速度,就需要犧牲一些寫入資料的效能以完成索引的建立,反之,如果想獲得更快的寫入速度,往往要放棄一些索引的建立,就勢必在查詢的時候付出更高的效能代價。
而Druid剛好能夠同時提供效能卓越的實時攝入與複雜的效能查詢。這些都是基於其獨到的架構設計與資料結構優秀設計實現的。

下面是Druid的架構設計與資料結構簡單介紹

Druid 總體架構包含四類節點:
1.實時節點:即時攝入資料,以及生成Segment資料檔案
2.歷史節點:載入以生成好的資料檔案,以及提供 資料查詢
3.查詢節點:對外提供資料查詢服務,並同時從實時節點與歷史節點查詢資料,合併後返回給呼叫方。
4.協調節點:負責歷史節點的資料負載均衡,以及通過規則管理資料的生命週期

機群包括的外部依賴:
1.元資料庫:儲存Druid叢集的原資料資訊,比如Segment的相關資訊,一般用MySQL或PostgreSQL
2.分散式協調服務:為Druid叢集提供一致性協調服務的元件,通常為Zookeeper
3.資料檔案儲存庫:存放生成的Segment資料檔案,並提供歷史節點下載。對於單節點叢集可以是本地磁碟,而對於分散式叢集一般是HDFS 或NFS

資料通過實時節點(實時)或者索引節點(批量)傳送到Druid集群后,實時節點對實時資料進行消費,然後生成一個個Segment資料檔案,並週期性的合併成一個大的Segment檔案上傳到資料檔案儲存庫,批量的資料會直接上傳到資料檔案儲存庫,同時查詢節點會相應外部的查詢請求,並分別從實時節點與歷史節點查詢到的結果進行合併後返回。每個節點幹什麼事,提供什麼服務,都很明確清晰,也方便擴充套件,提供高可用。

Druid 的資料結構DataSource與Segment

1.DataSource:
類似RDBMS中的表,結構如下
時間列:表明每行資料的時間值,這個列是資料聚合與範圍查詢的重要維度
維度列:用來標識資料行的各個類別資訊,如應用、位置等
指標列:用於聚合和計算的列,如請求量、曝光量等

無論是實時資料消費還是批量資料處理,Druid在基於DataSource結構儲存資料的時即可選擇對任意的指標列進行聚合操作,該聚合操作主要基於維度與時間範圍兩方面:

同緯度列做聚合,所有的維度列的值都相同的時,這一類行資料符合聚合操作,比如 在一段時間類,收到了廣告上報的曝光資料 appId =1, positionId=1 都是相同的,Druid 會對該資料進行預聚合,如收到收到1000條這樣的曝光資料,Druid 系統中只會記錄一條 資料 :
appId positionId exposureTimes
1 1 1000
這樣能大大減少資料量的,增加查詢效率。

對指定的時間粒度的值做聚合:上面同緯度列做聚合是對一段時間,這裡可以指定時間,如1分鐘、一個小時、一天等,可以根據需求來做

2.Segment
DataSource 是一個邏輯概念,Segment是資料實際物理儲存的格式,Druid通過Segment實現了對資料的橫縱向切割操作,Druid 將不同時間範圍內的資料儲存在不同的Segment資料快中,按時間範圍查詢資料的時,僅需要訪問對應時間段內的這些Segment 資料塊,而不需要進行全表資料範圍查詢,這使效率得到極大的高。

看到DataSource 和 Segment 結構設計是不是想到了RDBMS中資料庫分割槽表結構設計呢?DataSource 是一張表,而Segment 代表表中一個個分割槽。Druid 高效的原因攝入資料的時候就對資料進行了預聚合大大減少了數量,在查詢的時候通過查詢節點發起請求,查詢節點會通過時間範圍找出對應的Segment 及儲存該Segment 的歷史節點和實時節點,併發的向這些節點發請請求,並對結果進行合併,假設需要查詢的Segment 分佈在3臺機器上,那麼就有3臺機器為你處理請求,而且Druid是記憶體為王的查詢分析系統,也就是說,當向這三臺機器發起查的時候,如果資料在記憶體中,那麼計算速度是相當快的,如果不在記憶體中,會先把資料載入到記憶體中並進行計算,多級快取這是架構中設計提高吞吐量常見的技術。