51CTO|苏宁6亿会员是如何做到快速精确分析的?( 三 )


文章图片
数据查询流程图
数据分析如上图:
①根据要查询的维度进行Cost分析判断 , 最终路由到预计算结果表、Cube_bitmap表、模型表进行数据分析 。
②从模型bitmap表或cube_bitmap表获取bitmap_cur和bitmap_sum , 从全量bitmap表中获取bitmap_all数据(flag=2并且日期是查询日期的前一天) 。
后续的bitmap位运算可在bitmap_cur、bitmap_sum和bitmap_all中进行 。
应用举例
①业务场景
业务场景如下图:
51CTO|苏宁6亿会员是如何做到快速精确分析的?
文章图片
51CTO|苏宁6亿会员是如何做到快速精确分析的?
文章图片
②设计方案
第一步:将买家的ID作为数据字典的信息 , 与对应的int或long形成关系映射存入全局字典表 。
第二步:统计每天的线上、线下的新老买家 , 统计维度根据渠道(线上和线下)+tag(1当天2历史)+日期 。
每天有两条统计信息 , 一个是当天的用户买家bitmap集合 , 一个是历史的用户买家bitmap集合 。
第二天统计基于第一天统计的集合和当天的集合做rb_or_agg , 形成一个新的当天历史bitmap集合(结果存储在Bitmap_Table_A) 。
第三步:基于统计维度(品类+渠道)+tag+日期来统计新老买家情况 , 每天也会有两条统计信息 , 一个是当天的一个是历史的 , 当天统计的是所有的品类和渠道做的groupby统计 , 统计bitmap集合打上标签为flag=1 , 历史flag=2是基于前一天历史加上当天统计的集合做rb_or_agg , 形成一个新的当天历史bitmap集合(结果存储在Bitmap_Table_B) 。
③场景分析
场景一:0428线上新买家
51CTO|苏宁6亿会员是如何做到快速精确分析的?
文章图片
统计0428线上新买家实则就是bitmap集合{A , D}和bitmap集合{A , C}进行rb_andnot_cardinality位运算 , 结果为{D} , 新买家的数量为1 。
场景二:0428线上空调新买家
51CTO|苏宁6亿会员是如何做到快速精确分析的?
文章图片
统计0428线上空调新买家则就是bitmap集合{C , A}和bitmap集合{C}进行rb_andnot_cardinality位运算 , 结果为{A} , 新买家的数量为1 。
0428线上冰洗新买家则是bitmap集合{D}和bitmap空集合做rb_andnot_cardinality位运算 , 结果为{D} , 数量为1 。
场景三:0428线上空调新买家中有多少是线上新买家
【51CTO|苏宁6亿会员是如何做到快速精确分析的?】统计则根据和Bitmap_Table_A和Bitmap_Table_B做rb_and_cardinality操作 , 则拿bitmap集合{A}和bitmap集合{{A , C}}进行rb_andnot_cardinality位运算 , 结果为空集 , 数量为0 。
0428线上冰洗新买家则根据bitmap集合{D}和bitmap集合{A , C}进行rb_andnot_cardinality位运算 , 运算结果bitmap集合为{D} , 数量为1 。
0428线上新买家品类分布即为:基于Bitmap_Table_B表 , 0428线上品类有冰洗{D}和空调{A} , 基于Bitmap_Table_A表统计线上历史买家为{A , C} 。
线上新买家冰洗则拿{D}和{A , C}做rb_andnot_cardinality后的集合为{D} , 数量为1 。
线上新买家空调则是拿{A}和{A , C}做rb_andnot_cardinality后的集合为空集 , 数量为0 。
不足与挑战
基于PostgreSQL+Citus的RoaringBitmap技术方案 , bitmap集合之间的位运算性能表现的较为卓越 , 但在很多业务场景需要高基数的bitmap集合进行位运算 。
基于Citus我们分析发现 , 在位运算的时候CPU利用率处于低位 , 后期我们也针对基于Citus做了优化 。
如bitmap下压到Work运算降低CN运算量 , 创建cube降低基数 , 在一定的程度了提高了效率 , 然在Ctius下的CPU始终没有得到充分利用 。