首頁>科技>

出處:https://zhuanlan.zhihu.com/p/272200536

一、背景

奕星 (EAS) 是騰訊內部專注於遊戲營銷活動分析的系統,在營銷活動效果分析中,奕星遇到一個最大的問題就是對活動參與人數的去重,並給出對應的活動號碼包。單個營銷活動的週期是固定的,但活動與活動之間時間很少會有完全相同的情況。

比如A活動時間是1-10號,B活動是5-15號,那麼如果想分別得到 A 和 B 的去重參與人數,則必須分別開啟任務對 A 和 B 在他們所屬的時間區間內進行計算去重。在海量日誌中每天對數千個營銷活動進行類似計算,對資源消耗是一個不小的挑戰。

而實際情況下,需要計算的任務量還遠遠不止於此,奕星同時還提供遊戲官網非活動連結的去重資料,甚至每個連結在每個推廣渠道的去重資料,這個任務量級目前高達每天 50W+ 以上。

總結來看,面臨的主要問題就是如何在海量資料的情況下,處理數量巨大的而且週期各不相同的去重計算任務。

二、原有解決方案

對於這個問題,奕星之前嘗試了不少方案,這裡簡單介紹一下。

1. 基於TDW臨時表的方案

TDW 是騰訊內部通用的一站式大資料平臺,服務穩定,功能強大。對於這些任務的計算,奕星最早是想借助於 TDW 的計算能力來完成。

思路很簡單,就是在 pysql 中迴圈對每個活動執行對應的 hiveSQL 來完成 T+1 時效的計算。

但這個方案最大的缺點就是:任務基本都是順序執行,重複掃描大量日誌,導致效率非常低下,而且從HDFS中拉取最終的去重檔案也非常耗時。

雖然後面採用多種思路最佳化,比如將原始日誌先每天統一批次去重一次入到臨時表裡,所有計算基於臨時表來完成等,但最終還是效率無法進一步提高而放棄。

2. 基於實時計算+檔案增量去重的方案

在奕星的資料統計中,基於 Storm 的實時計算任務,主要是提供各個活動的實時 PV 和參與次數等計數類資料。

由於記憶體資源有限,業界也有基於近似去重演算法(如 hyperloglog )直接在 Storm 中算出近似去重結果的,但無法給出精確的結果和最終的號碼包檔案,所以不符合選型要求。

而記憶體資源有限,更不可能容納下這麼大量的號碼包資料,所以透過記憶體完全得出最終精確去重結果的方案基本不現實。

但記憶體雖然不能容納整個活動期間的號碼資料或者一天之內的號碼資料,但是否可以容納 1 分鐘,5 分鐘的號碼資料?

透過測試計算發現,在記憶體中快取 5 分鐘內的去重號碼資料是完全可行的,並且最高可以將原始日誌降低 90% 以上的量級。快取 1 分鐘的話,最高也可以將原始日誌降低 70% 以上的量級。

主要的原因是玩家參與活動的時候是即時參與行為,比如一個玩家來到一個活動頁面後,一般是連續將活動中能參與的功能都參與下,不會參與完一個等很久再參與下一個,所以導致同一個玩家的日誌時間連續性較高,單位時間視窗內去重後量級會降低很多。

基於此,目前奕星主要是基於 Storm 在單位時間視窗內進行初次去重,以達到降低原始資料量級的目的。

最初的基於 TDW 的去重方案,除了重複掃描等問題外,還有一個問題就是:同一個活動不同日期之間的計算無法前後銜接,比如 A 活動在活動期間(1-10號),每天的計算邏輯基本一致,都是要全量掃描 1-10 號之間的日誌(或中間結果)來完成計算。

所以團隊將目光投向如何在活動前期去重的基礎上來增量去重的問題上來。最終選定的方案是基於檔案的計算方案,如下圖所示,活動每天都滾動生成最新的去重號碼包檔案,而次日同一個活動的日號碼包再與這個總包交叉後得到更新的號碼包檔案,如此重複,直到活動結束得到最終的活動號碼包檔案。

3. 基於實時計算+LevelDB增量去重方案

檔案增量去重的方案,運行了一段時間後,就出現了一個很大的問題:就是每日新增的檔案量巨大,日均幾十萬。

雖然沒有達到把單臺機器 inode 佔滿的情況,但在增量去重時,大量的小檔案 IO 操作,導致增量去重效率非常低,最後被迫只支援高優先順序業務的活動和單個活動參與量大於一定閥值的大活動。

經過團隊小夥伴的調研,最終將目光鎖定在 Google 的 LevelDB 上,LevelDB 是 Google 開源的持久化 KV 單機資料庫,具有很高的隨機寫,順序讀/寫效能,但是隨機讀的效能很一般。

也就是說,LevelDB 很適合應用在查詢較少,而寫入很多的場景,這正好符合我們號碼包去重服務的應用場景。

另外號碼包的儲存本身也是一個K-V的儲存,檔名為 key,檔案內容為 value,正好跟 LevelDB 支援的 K-V 結構類似。

使用 LevelDB 後,可以毫秒級得到某個活動的準確去重人數,並且可以在 10 秒內匯出千萬量級的號碼包檔案,相比傳統的檔案操作,大大提高了號碼包去重服務的整體效率。

三、基於CLickHouse的解決方案

雖然基於 LevelDB 的去重服務可以很好的滿足大部分營銷活動的人數去重需求。但擴充套件性較差,資料回溯困難等問題比較突出,類似於基於預計算模式的 OLAP 系統。比如系統只支援活動整個期間內的去重人數計算,如果想知道活動期間內某一段時間內的去重就無法實現。

基於 MPP 的 OLAP 系統,在資料庫非共享叢集中,每個節點都有獨立的磁碟儲存系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺數據節點透過專用網路或者商業通用網路互相連線,彼此協同計算,作為整體提供資料庫服務。

相對於基於預計算模式的 OLAP 系統來說,它最大的優點就是靈活,擴充套件性強,而最大的缺點是響應時間不及時,甚至需要較長的時間等待。

而在營銷活動效果分析中,往往靈活性比效率要更加重要,或者說效率是可以稍微妥協的一面,所以我們選擇基於 MPP 的 OLAP 系統。

目前市面上有很多優秀的 OLAP 系統,但要麼是收費的(Vertica),要麼是基於 hadoop 生態的(presto,Impala),整體架構比較重。

而作為戰鬥民族開源神器的 ClickHouse 不但擁有自己的檔案系統和極高的壓縮比,在叢集部署上甚至可以不用 zk 來獨立部署,甚至在效能上“吊打”商業的 OLAP 系統(詳見官方測評資料: https:// clickhouse.tech/benchma rk/dbms/ )。

綜合以上考慮,最終選擇了 ClickHouse,去重服務就變成了 SQL 查詢,例如下面這條 SQL 就是查詢 LOL 官網某個頁面在 9 月 6 日這 1 天的 UV:

select uniqExact(uvid) from tbUv where date='2020-09-06' and url='http://lol.qq.com/main.shtml';

在 24 核 96G 記憶體的機器上,實際測試下來在 1 億條記錄中,精確去重一個參與量為100W 的活動,僅需 0.1 s 不到,而匯出這個號碼包檔案只需要 0.2 s 不到。

雖然查詢效率上比 LevelDB 有一點差距,但靈活性卻大大提高,可以任意指定時間區間和條件來做去重查詢,符合當前業務場景關注靈活度的需求場景,而且效能上從毫秒到秒級的延遲基本也可以接受。

四、結語

去重服務的的問題伴隨奕星系統整個開發和運營週期,期間經歷過很多嘗試,部分臨時的嘗試方案尚未在本文列出,但一直的出發點就是業務需求本身,並且結合當時的運維環境來選取對應的技術方案。

不追求絕對的高效能(意味成本也高),而關注最合適,易於擴容,搬遷,故障替換等有利於服務長期穩定運營的特性。當然,隨著更多利器的出現,也會去不斷的嘗試使用,畢竟科學技術才是第一生產力。

目前 ClickHouse 在奕星等多個數據系統和諸多個性化營銷分析的場景中落地使用,資料總規模超過 5 千億,還在不斷增長中。

出處:https://zhuanlan.zhihu.com/p/272200536

2
  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • 保護網際網路隱私權應提升監管力度