Hologres如何支持超高基数UV计算(基于roaringbitmap实现)

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
简介: 本文将会介绍Hologres基于roaringbitmap实现超高基数的UV计算

RoaringBitmap是一种压缩位图索引,RoaringBitmap自身的数据压缩和去重特性十分适合对于大数据下uv计算。其主要原理如下:

  • 对于32bit数, RoaringBitmap会构造2^16个桶,对应32位数的高16位;32位数的低16位则映射到对应桶的一个bit上。单个桶的容量由桶中的已有的最大数值决定
  • bitmap把32位数用1位表示,可以大大地压缩数据大小。
  • bitmap位运算为去重提供了手段。

主体思想(T+1):把上一天的所有数据根据最大的查询维度聚合出的uid结果放入RoaringBitmap中,把RoaringBitmap和查询维度存放在聚合结果表(每天百万条)。之后查询时,利用Hologres强大的列存计算直接按照查询维度去查询聚合结果表,对其中关键的RoaringBitmap字段做or运算进行去重后并统计基数,即可得出对应用户数UV,count条数即可计算得出PV,达到亚秒级查询。

只需进行一次最细粒度的预聚合计算,也只生成一份最细粒度的预聚合结果表。得益于Hologres的实时计算能力,该方案下预计算所需的次数和空间都达到较低的开销。

Hologres计算UV、PV方案详情

uv1.jpeg

图1 Hologres基于RoaringBitmap计算pv uv流程


1.创建相关基础表

1)使用RoaringBitmap前需要创建RoaringBitmap extention,语法如下,同时该功能需要Hologres  0.10版本。

CREATE EXTENSION IF NOT EXISTS roaringbitmap;

2)创建表ods_app为明细源表,存放用户每天大量的明细数据 (按天分区),其DDL如下:

BEGIN;CREATETABLE IF NOT EXISTS public.ods_app(     uid text,     country text,     prov text,     city text,     channel text,     operator text,     brand text,     ip text,     click_time text,yeartext,     month text,     day text,     ymd textNOTNULL);CALL set_table_property('public.ods_app','bitmap_columns','country,prov,city,channel,operator,brand,ip,click_time, year, month, day, ymd');--distribution_key根据需求设置,根据该表的实时查询需求,从什么维度做分片能够取得较好效果即可CALL set_table_property('public.ods_app','distribution_key','uid');--用于做where过滤条件,包含完整年月日时间字段推荐设为clustering_key和event_time_columnCALL set_table_property('public.ods_app','clustering_key','ymd');CALL set_table_property('public.ods_app','event_time_column','ymd');CALL set_table_property('public.ods_app','orientation','column');COMMIT;

3)创建表uid_mapping为uid映射表,uid映射表用于映射uid到32位int类型。

RoaringBitmap类型要求用户ID必须是32位int类型且越稠密越好(用户ID最好连续),而常见的业务系统或者埋点中的用户ID很多是字符串类型,因此使用uid_mapping类型构建一张映射表。映射表利用Hologres的SERIAL类型(自增的32位int)来实现用户映射的自动管理和稳定映射。

注: 该表在本例每天批量写入场景,可为行存表也可为列存表,没有太大区别。如需要做实时数据(例如和Flink联用),需要是行存表,以提高Flink维表实时JOIN的QPS。

BEGIN;CREATETABLE public.uid_mapping(     uid textNOTNULL,     uid_int32 serial,            PRIMARY KEY (uid));--将uid设为clustering_key和distribution_key便于快速查找其对应的int32值CALL set_table_property('public.uid_mapping','clustering_key','uid');CALL set_table_property('public.uid_mapping','distribution_key','uid');CALL set_table_property('public.uid_mapping','orientation','row');COMMIT;

3)创建表dws_app基础聚合表,用于存放在基础维度上聚合后的结果

基础维度为之后进行查询计算pv和uv的最细维度,这里以country, prov, city为例构建聚合表

begin;createtable dws_app(    country text,  prov text,  city text,  ymd textNOTNULL,--日期字段  uid32_bitmap roaringbitmap,-- UV计算  pv integer,-- PV计算  primary key(country, prov, city, ymd)--查询维度和时间作为主键,防止重复插入数据);CALL set_table_property('public.dws_app','orientation','column');--clustering_key和event_time_column设为日期字段,便于过滤CALL set_table_property('public.dws_app','clustering_key','ymd');CALL set_table_property('public.dws_app','event_time_column','ymd');--distribution_key设为group by字段CALL set_table_property('public.dws_app','distribution_key','country,prov,city');end;

2.更新dws表及id_mapping表

每天从上一天的uid中找出新客户(uid映射表uid_mapping中没有的uid)插入到uid映射表中

WITH
-- 其中ymd = '20210329'表示上一天的数据    user_ids AS(SELECT uid FROM ods_app WHERE ymd ='20210329'GROUPBY uid ),new_ids AS(SELECT user_ids.uidFROM user_ids LEFT JOIN uid_mapping ON(user_ids.uid= uid_mapping.uid)WHERE uid_mapping.uidISNULL)INSERTINTO uid_mapping SELECT  new_ids.uidFROM    new_ids
;

更新完uid映射表后,将数据做聚合运算后插入聚合结果表,主要步骤如下:

  • 首先通过源表inner join uid映射表,得到上一天的聚合条件和对应的uid_int32;
  • 然后按照聚合条件做聚合运算后插入RoaringBitmap聚合结果表,作为上一天的聚合结果;
  • 每天只需进行一次聚合,存放一份数据,数据条数最坏等于UV的量。以案例说明,明细表每天几亿的增量,在聚合结果表每天只需存放百万级数据。
WITH
    aggregation_src AS(SELECT country, prov, city, uid_int32 FROM ods_app INNER JOIN uid_mapping ON ods_app.uid= uid_mapping.uidWHERE ods_app.ymd='20210329')INSERTINTO dws_app SELECT  country
,prov
,city
,'20210329',RB_BUILD_AGG(uid_int32),COUNT(1)FROM    aggregation_src
GROUPBY country
,prov
,city
;

3.UV、PV查询

查询时,从汇总表dws_app 中按照查询维度做聚合计算,查询bitmap基数,得出Group by条件下的用户数

--运行下面RB_AGG运算查询,可先关闭三阶段聚合开关性能更佳(默认关闭)set hg_experimental_enable_force_three_stage_agg=off    
--可以查询基础维度任意组合,任意时间段的uv pvSELECT  country
,prov
,city
,RB_CARDINALITY(RB_OR_AGG(uid32_bitmap))AS uv
,sum(1)AS pv
FROM    dws_app
WHERE   ymd ='20210329'GROUPBY country
,prov
,city;--查一个月         SELECT  country
,prov
,RB_CARDINALITY(RB_OR_AGG(uid32_bitmap))AS uv
,sum(1)AS pv
FROM    dws_app
WHERE   ymd >='20210301'and ymd <='20210331'GROUPBY country
,prov;该查询等价于
SELECT  country
,prov
,city
,COUNT(DISTINCT uid)AS uv
,COUNT(1)AS pv
FROM    ods_app
WHERE   ymd ='20210329'GROUPBY country
,prov
,city;SELECT  country
,prov
,COUNT(DISTINCT uid)AS uv
,COUNT(1)AS pv
FROM    ods_app
WHERE   ymd >='20210301'and ymd <='20210331'GROUPBY country
,prov;

4.可视化展示

计算出UV、PV和,大多数情况需要用BI工具以更直观的方式可视化展示,由于需要使用RB_CARDINALITY 和 RB_OR_AGG 进行聚合计算,需要使用BI的自定义聚合函数的能力,常见的具备该能力的BI包括Apache Superset和Tableau,下面将会讲述这两个BI工具的最佳实践。

4.1 使用 Apache Superset

Apache Superset 对接 Hologres 的方式,请参考产品手册。在Superset中可以直接使用dws_app表作为Dataset使用

uv2.png

并且在数据集中,创建一个单独Metrics,名为UV,表达式如下:

RB_CARDINALITY(RB_OR_AGG(uid32_bitmap))

uv3.png

然后您就可以开始探索数据了

uv4.png

uv5.png

当然也可以创建Dashborad:

uv6.png

4.2 使用 Tableau

Tableau 对接 Hologres 的方式,请参考产品手册。可以使用Tableau的直通函数直接实现自定义函数的能力,详细介绍请参照Tableau的手册。在Tableau对接Hologres后,可以创建一个计算字段,表达式如下

RAWSQLAGG_INT("RB_CARDINALITY(RB_OR_AGG(%1))",[Uid32 Bitmap])

uv7.png

然后您就可以开始探索数据了

uv8.png

当然也可以创建Dashborad

uv9.png

相关实践学习
基于Hologres轻松玩转一站式实时仓库
本场景介绍如何利用阿里云MaxCompute、实时计算Flink和交互式分析服务Hologres开发离线、实时数据融合分析的数据大屏应用。
相关文章
|
4月前
|
存储 数据挖掘 大数据
深度解析Hologres计算资源配置:如何根据业务场景选择合适的计算类型?
【8月更文挑战第22天】Hologres是一款由阿里云提供的分布式分析型数据库,支持高效的大数据处理与分析。本文通过电商优化商品推荐策略的案例,介绍了Hologres中的计算组型与通用型配置。计算组型提供弹性扩展资源,适合大规模数据及高并发查询;通用型则适用于多数数据分析场景,具备良好计算性能。通过实例创建、数据加载、计算任务建立及结果查询的步骤展示,读者可理解两种配置的差异并根据业务需求灵活选择。
64 2
|
4月前
|
存储 SQL API
实时数仓 Hologres产品使用合集之如何使用Hologres的Roaringbitmap
实时数仓Hologres是阿里云推出的一款高性能、实时分析的数据库服务,专为大数据分析和复杂查询场景设计。使用Hologres,企业能够打破传统数据仓库的延迟瓶颈,实现数据到决策的无缝衔接,加速业务创新和响应速度。以下是Hologres产品的一些典型使用场景合集。
|
4月前
|
DataWorks 调度 数据库
实时数仓 Hologres产品使用合集之通用和计算组型有什么区别
实时数仓Hologres是阿里云推出的一款高性能、实时分析的数据库服务,专为大数据分析和复杂查询场景设计。使用Hologres,企业能够打破传统数据仓库的延迟瓶颈,实现数据到决策的无缝衔接,加速业务创新和响应速度。以下是Hologres产品的一些典型使用场景合集。
|
5月前
|
存储 SQL 分布式计算
|
7月前
|
存储 SQL 分布式计算
Hologres RoaringBitmap在Lazada选品平台的最佳实践
Lazada选品平台包含全网商家、商品的圈选,通过Hologres RoaringBitmap能力帮助业务突破选品池20w大小限制,6000+选品池调度完成由12h下降至1h,单个选品池调度时间由90s下降至2s。
|
7月前
|
测试技术 数据库
实时数仓 Hologres产品使用合集之计算型和通用型的区别是什么
实时数仓Hologres是阿里云推出的一款高性能、实时分析的数据库服务,专为大数据分析和复杂查询场景设计。使用Hologres,企业能够打破传统数据仓库的延迟瓶颈,实现数据到决策的无缝衔接,加速业务创新和响应速度。以下是Hologres产品的一些典型使用场景合集。
|
7月前
|
存储 SQL 弹性计算
Hologres V2.1版本发布,新增计算组实例构建高可用实时数仓
新增弹性计算组实例,解决实时数仓场景下分析性能、资源隔离、高可用、弹性扩缩容等核心问题,同时新增多种用户分析函数与实时湖仓Paimon格式支持,COUNT DISTINCT优化显著提升查询效率。
|
7月前
|
存储 分布式计算 MaxCompute
Hologres RoaringBitmap实践:千亿级画像数据秒级分析
Hologres RoaringBitmap实践:千亿级画像数据秒级分析
836 2
|
存储 自然语言处理 机器人
基于Hologres向量计算与大模型免费定制专属聊天机器人
本文为您介绍如何基于Hologres向量计算能力,结合大模型的阅读理解和信息整合能力,对该垂直行业的问题提供更贴切的回答,即费、快速定制专属聊天机器人。
基于Hologres向量计算与大模型免费定制专属聊天机器人
|
存储 分布式计算 MaxCompute
Hologres RoaringBitmap实践,千亿级画像数据秒级分析
本文将会分享Hologres RoaringBitmap 方案在画像分析的应用实践,实现更快更准的画像分析。

相关产品

  • 实时数仓 Hologres
  • 下一篇
    DataWorks