Hologres如何支持亿级用户UV计算
簡介: 本文將介紹阿里云Hologres如何基于RoaringBitmap進行UV等高復雜度計算的方案,實現億級用戶萬級標簽亞秒級分析,幫助用戶從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來說,去做精確去重和累加計算則更為靈活:
- 明細數據不多或者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等原生表達式,對指標進行預聚合運算。但是同樣也會存在數據膨脹問題,一般情況下按照上述方案即可。
?
綜上所述,Kylin對可累加指標或精確去重指標的查詢時,需構建Cube才能獲取較高性能,這將引入額外的預計算和數據膨脹。而Hologres則更為靈活:
-
- 對于DWD層數據量不大或者查詢QPS要求不高的場景,無需預計算,可直接在DWD層上進行查詢,即可獲得很好的性能與最大的靈活性;
- 對于DWD層數據量較大且有高QPS查詢的場景,可根據基礎維度進行一次預計算,并只生成一份DWS表,查詢時按需選取維度查詢即可。不會引入過多的預計算和數據膨脹問題。
?
本文下面將會介紹基于Hologres的DWS層構造和查詢方案。
遷移可累加指標
?
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, dim2where ymd ='20210426';select count(distinct uid) as uv, count(1) as pv from src_t group by dim1, dim5, dim9where ymd like '202103%'; --查詢區間為3月份--group by的字段是固定維度的中任意維度的組合 --where 過濾的區間范圍 從一天到半年不等--因此有多少維度和時間的組合需求,就需要查詢多少個這樣count distinct sql,每條在查詢時都需要大量計算這種方式下,根據查詢區間,每次查詢要對幾億條到幾十億甚至幾百億條數據進行多個維度的Group by,然后再使用COUNT DISTINCT進行精確去重,會產生大量的數據交換計算,實時地得到結果需要一定量的計算資源,大大增加用戶的成本。
?
基于Bitmap方式計算精確去重
Hologres內置Bitmap類型,通過計算一定維度組合條件下的Bitmap結果集,把維度的所有組合生成預計算的結果表,簡單原理如下:
查詢時,根據查詢時的維度,查詢對應的預計算結果表對桶進行聚合運算即可達到亞秒級查詢。
--計算bitmapinsert into result_t select RB_BUILD_AGG(uid) as uv_bitmap, count(1) as pvfrom src_tgroup 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_twhere ymd >= '20210301' and ymd <= '20210331'?
后面我們將會陸續推出Hologres基于RoaringBitmap的高效UV計算最佳實踐,主要內容如下,敬請期待:
- Hologres使用RoaringBitmap實現高效UV計算
- Hologres使用Flink+RoaringBitmap實現實時UV計算
參考文檔
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
原文鏈接
本文為阿里云原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的Hologres如何支持亿级用户UV计算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据湖 VS 数据仓库之争?阿里提出大数
- 下一篇: Java编程技巧之样板代码