前言
在电商中,基于用户画像标签进行人群筛选,并对相应人群进行APP消息,短信链接推送等是个特别常见的场景,我们平时所了解的精准营销,用户触达也都是基于此实现的。我司目前用户人群筛选主要基于以下几种技术方案:
impala + hbase +hive
用户标签存储在hbase中,将hbase中的表映射成hive表,并基于impala查询hive,达到实时查询的效果
presto + hive
直接使用presto查询用户画像打平hive表
基于hbase原生API
对于一些存储在hbase复杂的标签(主要是针对带有多版本的字段)进行原生api查询
以上技术方案目前都存在各自的短板,第一种方案涉及到hbase表与hive表的映射,字段增添删减时,都需要去维护表结构;第二种方案,由于presto都是将数据加载到内存中计算,所以在请求查询数较多时,目前需要“排队”,否则会撑爆内存,另外查询条件复杂时响应结果时间较长;第三种方案,基于hbase原生api,需要针对不同的字段类型,不同的查询类型,自定义各种filter,代码实现相当复杂,同样在查询条件复杂时,响应时间较长。
Bitmap介绍
在介绍Clickhouse中的Bitmap在用户画像场景下的应用之前,先简单介绍一下Bitmap数据类型。
对于大数据场景处理,海量数据的判重和基数统计是绕不开的问题,几乎每张指标统计报表都会有对应的指标,对此比较常用的方法有布隆过滤器,HyperLogLog等,利用它们可以节省大量存储空间并且保证了计算效率,但是不足的是不能保证100%精确,会存在误差。
而Bitmap(位数组)就是上述两种方法的基础,我们可以先看一个常见的问题,我们如何利用较少的空间来存储40亿个不重复的位于[0- 2^32-1]区间内整数的集合?
按照正常思路,[0- 2^32-1]区间范围正是Java中Int无符号的取值范围,每个Int整数占4个字节,即32个bit。那么40亿个所占空间大小为 40*10^8*4B / 1024/1024/1024=14.9GB,将近15G的存储空间,显然是耗费资源的。
如果用Bitmap来存储呢,第0个比特表示数字0,第1个比特表示数字1&