在用户行为分析和圈人场景中,经常需要从亿级甚至几十亿级用户中快速筛选出符合特定标签的指标结果,本文为您介绍Hologres中如何进行用户行为分析。

行业背景与痛点

UV(Unique Visitor)是行为分析中最常见的指标,代表访问网页的自然人,可以引申为某段时间内某个指标精确去重后的量。例如大促时,电商商家需要实时计算店铺的实时UV,并根据UV情况及时调整运营策略,从而达成销售目标。

在计算用户UV时,由于业务需求不同,计算的维度和数据量也不同,通常来讲会有以下诉求。
  • 用户数据量大,每天几亿条,维度多(10+以上),需要支持各维度间任意组合查询。
  • 查询时间需要更灵活,不仅局限于天、周、月、年等,还需要支持更细粒度实时更新查询。
  • 需要对用户数量精确去重。
面对上诉高复杂度UV计算场景,业界常见的手段包括使用Apche Kylin等预计算系统或者Flink+MySQL的固定维度组合方案,但这些方案会遇见以下痛点。
  • 需求维度过多时,会带来存储爆炸,预计算时间长。
  • 精确去重需要消耗大量资源,容易出现OOM(Out Of Memory)。
  • 实时更新难,无法支持更加灵活开放的时间周期处理。

解决方案与优势

Hologres是基于分析服务一体化理念(Hybrid Serving & Analytical Processing,HSAP)设计的实时数仓产品,采用分布式架构,支持数据实时写入,高并发、低延时的分析处理PB级数据,兼容PostgreSQL协议,使用最熟悉的工具就能进行开发。

在Hologres中,通过RoaringBitmap和Serial,结合Hologres自身的高性能,就能实现亿级UV精确计算。
  • RoaringBitmap
    RoaringBitmap是一种压缩位图索引,RoaringBitmap自身的数据压缩和去重特性十分适合对于大数据下UV计算。其主要原理如下:
    • 对于32Bit数,RoaringBitmap会构造216个桶,对应32位数的高16位;32位数的低16位则映射到对应桶的一个Bit上。单个桶的容量由桶中已有的最大数值决定。
    • Bitmap把32位数用1位表示,可以极大的压缩数据。
    • Bitmap位运算为去重提供了手段。
    RoaringBitmap使用详情请参见Roaring Bitmap函数
  • Serial

    自增序列Serial,常用于维表关联中的用户映射(user_mappping)。因为常见的业务系统或者埋点中的用户ID很多是字符串类型或Long类型,因此需要使用uid_mapping类型构建一张映射表。RoaringBitmap类型要求用户ID必须是32位INT类型且越稠密越好(即用户ID最好连续),映射表利用Hologres的SERIAL类型(自增的32位INT)来实现用户映射的自动管理和稳定映射。Serial使用详情请参见自增序列Serial(Beta)

离线UV计算场景

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

只需进行一次最细粒度的预聚合计算,也只生成一份最细粒度的预聚合结果表。得益于Hologres的计算能力,该方案下预计算所需的次数和空间都达到较低的开销。详情使用请参见离线UV计算

实时UV计算场景

Hologres与Flink有着强大的融合优化,支持Flink数据高通量实时写入,写入即可见,支持Flink SQL维表关联,以及作为CDC Source事件驱动开发。

实时UV计算主要是Hologres与Flink结合完成:Flink关联Hologres用户维表,并基于RoaringBitmap,实时对用户标签去重。这样的方式,可以较细粒度的实时得到用户UV、PV数据,同时便于根据需求调整最小统计窗口(如最近5分钟的UV),实现类似实时监控的效果,更好的在大屏等BI中展示。相较于以天、周、月等为单位的去重,更适合在活动日期进行更细粒度的统计,并且通过简单的聚合,也可以得到较大时间单位的统计结果。

该方案数据链路简单,可以任意维度灵活计算,只需要一份Bitmap存储,也没有存储爆炸问题,还能保证实时更新,从而实现更实时、开发更灵活、功能更完善的多维分析数仓。使用详情请参见实时UV精确去重(Flink+Hologres)