天天看點

Hologres如何支援億級使用者UV計算背景介紹Apache Kylin與Hologres的對比使用Hologres方案的收益:實時、靈活、簡單如何從Kylin遷移到Hologres實作原理遷移可累加名額遷移不可累加名額(精确去重場景)參考文檔

背景介紹

在使用者行為分析和圈人場景中,經常需要從億級甚至十億級使用者中快速篩選出符合特定标簽的使用者統計,很多企業會使用Apache Kylin(下文簡稱Kylin)來支援這樣的場景。但是Apache Kylin的核心是預計算,當遇上設計不合理的Cube,或者需求次元多的場景時,會遇到次元爆炸,Cube建構時間長,SQL函數不支援等問題。

本文将介紹阿裡雲Hologres如何基于RoaringBitmap進行UV等高複雜度計算的方案,實作億級使用者萬級标簽亞秒級分析,幫助使用者從Kylin平滑遷移到Hologres,實作更實時、開發更靈活、功能更完善的多元分析能力。

Apache Kylin與Hologres的對比

對比項 Apache Kylin Hologres 差異點
定位 MOLAP on Hadoop Real-Time MPP Data Warehouse -
模組化方式 星型、雪花模型 寬表模型、主題模型 Hologres無需複雜模組化理論和模組化過程,資料導入即可查
核心原理 空間換時間,減少運作時計算,預計算Cube,依賴Hadoop 并行計算、列存、向量化,充分利用多節點,多核計算資源 Hologres沒有存儲爆炸問題,無需預建構等待
運維方式 依賴YARN,HBase,ZK等,外部依賴多 計算存儲分離,彈性伸縮,更新平滑,無外部依賴 Hologres托管式運維,運維簡單,無需Hadoop技能
使用場景 固定報表,固定次元組合,固定名額服務,秒級響應 靈活自助報表、自助式分析、探索式分析、自助取數、線上資料服務,秒級響應 Hologres分析更靈活,無限制,支援完善的SQL Join,嵌套查詢,視窗函數等
查詢接口 自定義JDBC,ODBC,有限SQL能力 相容PostgreSQL,标準JDBC、ODBC,支援标準SQL Hologres相容開源生态,SQL标準
開發效率 依賴于模組化人員的熟練度,掌握Kylin的複雜模組化技巧 針對“表”設計,概念簡單 Hologres上手容易,學習門檻低
資料時效性 T+1,加工流程長,資料修正慢,模型修改成本非常高 實時,寫入即可查,資料可更新,模型可變更 Hologres T+0,全實時

使用Hologres方案的收益:實時、靈活、簡單

基于上述的比較,我們看到Kylin和Hologres擁有一些共同的場景:海量資料互動式分析、亞秒級響應、橫向擴充能力。Kylin有很多優點,包括:最小化查詢開銷,以點查的性能完成多元分析,查詢性能更穩定,利用Bitmap支援全局精确去重。同時也發現了一些Kylin的使用難點,包括:模組化複雜(主要由IT團隊負責模組化),Cube膨脹(存儲成本高),建構Cube時間長(業務不實時,建構任務資源消耗大),模型不可變(業務不靈活),SQL支援能力弱(固定的Join連接配接條件、有限的SUM COUNT算子,BI相容度低,SQL協定不标準),可擴充能力弱(UDF少)。

遷移到Hologres之後,可以獲得的收益包括:模組化簡單(面向表,DWD&DWS),SQL能力強(相容PostgreSQL11,支援Ad-Hoc Query),資料鍊路實時(寫入即可見),運維簡單(無Hadoop依賴)

如何從Kylin遷移到Hologres

  • 架構調整:從Hadoop/HBase架構,調整到MPP資料倉庫Hologres,去Hadoop,ZK等依賴
  • 模組化上:從面向名額的多元模組化,調整為面向表的DWD、DWS分層模組化,DWD為主,性能敏感時補充DWS甚至ADS,關注Query SLA,避免超大Query,通過基礎聚合結果集作為輕量彙總的DWS,滿足95%場景。
  • 學習上:學習Cube優化技巧到學習Hologres索引設計、查詢優化、資源監控
  • 存儲上:從單一的HBase存儲,到冷熱資料分層存儲(Hologres+MaxCompute)
  • 場景上:通過Hologres提供更靈活、更靈活的自助式分析,加速資料産品創新
  • 分工上:IT從關注模組化的建構品質到關注平台的開發效率,更多服務業務價值

實作原理

在場景遷移之前,首先介紹以下精确去重和累加計算在Kylin和Hologres上不同的實作方式,以便于根據不同場景選用不同的方式去遷移原有業務。

如下圖所示,Kylin根據次元和度量,進行多次預計算生成2^n個cuboid(n為次元數量)來建構cube。查詢時,根據查詢的次元,映射到相應的cuboid得到度量結果。Cube相比原始明細資料會有N倍的資料膨脹,且非常不靈活。

Hologres如何支援億級使用者UV計算背景介紹Apache Kylin與Hologres的對比使用Hologres方案的收益:實時、靈活、簡單如何從Kylin遷移到Hologres實作原理遷移可累加名額遷移不可累加名額(精确去重場景)參考文檔

圖1 Kylin精确去重和累加計算實作

對于Hologres來說,去做精确去重和累加計算則更為靈活:

  • 明細資料不多或者QPS要求不高的場景:直接利用SQL語句從明細表中對統計次元進行Group by,對名額用聚合函數計算度量結果。這種方法可以獲得最大的靈活性,能充分利用Hologres強大的計算能力,可進行任意複雜的查詢,實作數億條記錄的毫秒級分析。
  • 資料量大且高QPS場景:在Hologres中将明細表按照基礎次元最細粒度做Group by,對名額進行預聚合運算生成一份DWS表。查詢時對DWS表按照統計次元Group by,對名額的預聚合結果進行聚合計算即可。通過DWS層,極大的減少資料量,進而實作高QPS的查詢要求。相比于DWD(明細層),DWS層的資料量正常隻有DWD層的1/100甚至更少,這點類似于Kylin中的Base Cuboid結構。
  • 當然在Hologres上也可以采用類似Kylin建構Cube的方式:将明細表按照所需的各種次元組合做Group by,或者Cube、Rollup、Grouping Sets等原生表達式,對名額進行預聚合運算。但是同樣也會存在資料膨脹問題,一般情況下按照上述方案即可。
Hologres如何支援億級使用者UV計算背景介紹Apache Kylin與Hologres的對比使用Hologres方案的收益:實時、靈活、簡單如何從Kylin遷移到Hologres實作原理遷移可累加名額遷移不可累加名額(精确去重場景)參考文檔

圖2 Hologres不同場景下精确去重和累加計算

綜上所述,Kylin對可累加名額或精确去重名額的查詢時,需建構Cube才能擷取較高性能,這将引入額外的預計算和資料膨脹。而Hologres則更為靈活:

    • 對于DWD層資料量不大或者查詢QPS要求不高的場景,無需預計算,可直接在DWD層上進行查詢,即可獲得很好的性能與最大的靈活性;
    • 對于DWD層資料量較大且有高QPS查詢的場景,可根據基礎次元進行一次預計算,并隻生成一份DWS表,查詢時按需選取次元查詢即可。不會引入過多的預計算和資料膨脹問題。

本文下面将會介紹基于Hologres的DWS層構造和查詢方案。

遷移可累加名額

  1. 明細資料導入Hologres,資料結構采用原始Hive中的事實表、次元表結構,可以通過“DataWorks資料內建批量同步”完成資料遷移。
  2. 資料源資料對應DWD層,包含明細資料和次元資料,如果資料是行為資料,根據日期字段建成分區表,如果是訂單資料,不需要分區表。
  3. 對于QPS要求不高的場景:DWD表通過JDBC、ODBC暴露給BI應用。
  4. 對于QPS要求高的場景:繼續加工DWD生成DWS表,在Hologres中,針對Cube的連接配接條件,生成基礎聚合表

    BasicSummaryTable

    ,如Kylin中

    Fact A left join Fact B

    ,名額:

    Sum(a), count(b)

    ,Hologres中執行

    insert into BasicSummaryTable(col1, col2, ..., coln, sum_a, count_b) select col1, col2, ..., coln, sum(a), count(b) from A left join b group by col1, col2, ..., coln

    . 結果儲存為BasicSummaryTable表。
  5. Hologres通過JDBC、ODBC暴露

    BasicSummaryTable

    表給BI應用。

DWS層的構造中,最重要的就是各種度量資料(名額)的聚合,需要保證各名額都是可累計的。對于SUM、COUNT、MIN、MAX、AVG(可通過保留兩個字段:sum和count來解決),名額的可累計是非常簡單的。

但對于COUNT DISTINCT類的名額(需要精确去重的名額,例如UV),也需要保證在DWS中,這個名額是可累計的,可通過Hologres原生支援的RoaringBitmap資料類型來進行計算和儲存。

遷移不可累加名額(精确去重場景)

下面通過一個案例介紹Hologres中通過DWS來計算大時間範圍的PV、UV的最佳實踐。

PV (Page View): 字面含義頁面通路量,比如一天内頁面的累計通路量。其實也可引申為某段時間内某個名額的累加量。比如:雙十一期間某件商品的點選量,活動促銷期間某個地區的訂單量等。

UV (Unique Visitor) : 通路網頁的自然人,如果有20個人一天通路某個頁面100次,這一天就是20個UV。可以引申為某段時間内某個名額精确去重後的量。

PV和UV是分析場景中比較重要的兩個名額,下面将以T+1離線場景為案例,進行PV UV計算的介紹。

案例背景

每天有幾億條資料,客戶總量千萬級,每日UV在百萬級,需要T+1根據十個左右次元(支援次元間任意組合)查詢一天,一周,或者一個月甚至半年期間相應的使用者數去重統計資訊,得出使用者數精确去重名額UV,以及通路量PV。

一般方式的UV PV計算

如果不采取任何預聚合運算,上述場景計算使用者數精确去重名額UV和通路量PV,SQL如下:

select count(distinct uid) as uv, count(1) as pv 
    from src_t 
    group by dim1, dim2
  where ymd ='20210426';

select count(distinct uid) as uv, count(1) as pv 
    from src_t 
  group by dim1, dim5, dim9
  where ymd like '202103%';  --查詢區間為3月份


--group by的字段是固定次元的中任意次元的組合
--where 過濾的區間範圍 從一天到半年不等

--是以有多少次元和時間的組合需求,就需要查詢多少個這樣count distinct sql,每條在查詢時都需要大量計算      

這種方式下,根據查詢區間,每次查詢要對幾億條到幾十億甚至幾百億條資料進行多個次元的Group by,然後再使用COUNT DISTINCT進行精确去重,會産生大量的資料交換計算,實時地得到結果需要一定量的計算資源,大大增加使用者的成本。

基于Bitmap方式計算精确去重

Hologres内置Bitmap類型,通過計算一定次元組合條件下的Bitmap結果集,把次元的所有組合生成預計算的結果表,簡單原理如下:

查詢時,根據查詢時的次元,查詢對應的預計算結果表對桶進行聚合運算即可達到亞秒級查詢。

--計算bitmap

insert into result_t select RB_BUILD_AGG(uid) as uv_bitmap, count(1) as pv
    from src_t
  group by dim, ymd;  --存在跨天查詢的需求,日期也必須加到group by次元中


--查詢時
select RB_CARDINALITY(RB_OR_AGG(uv_bitmap)), pv from result_t where ymd = '20210426'

select RB_CARDINALITY(RB_OR_AGG(uv_bitmap)), pv 
    from result_t
  where ymd >= '20210301' and ymd <= '20210331'
      

關于案例的最佳實踐,請繼續閱讀:

參考文檔

Apache Kylin:

http://kylin.apache.org/

Kylin精确去重:

https://blog.bcmeng.com/post/kylin-distinct-count-global-dict.html

Hologres RoaringBitmap函數:

https://help.aliyun.com/document_detail/216945.htm