两种模型分析
cube聚合结果冗余模型
- 查询事业部的数据:select bu_id, amount from table where dt=20211001 and bu_id>0 and cat1_id=-1 and cat2_id=-1;
dt | bu_id | cat1_id | cat2_id | amount |
---|---|---|---|---|
20211001 | 110100 | 1001 | 11001 | 100 |
20211001 | 110100 | 1001 | 11002 | 100 |
20211001 | 110100 | 1001 | -1 | 200 |
20211001 | 110100 | -1 | -1 | 200 |
20211001 | 310300 | 1001 | 11001 | 300 |
20211001 | 310300 | 1001 | -1 | 300 |
20211001 | 310300 | -1 | -1 | 300 |
20211001 | -1 | -1 | -1 | 500 |
基于明细的实时聚合模型
- 查询事业部的数据:select bu_id, sum(amount) as amount from table where dt=20211001 group by bu_id;
dt | bu_id | cat1_id | cat2_id | amount |
---|---|---|---|---|
20211001 | 110100 | 1001 | 11001 | 100 |
20211001 | 110100 | 1001 | 11002 | 100 |
20211001 | 310300 | 1001 | 11001 | 300 |
对比 | 细分对比 | cube聚合结果冗余模型 | 基于明细的实时聚合模型 |
---|---|---|---|
数据存储 | 数据条数 | ❌ 数据条数多(结果冗余),维度组合越多,维度粒度越细,数据条数膨胀越厉害 | ✅ 数据条数少,跟维度的粗细粒度有关系,维度越多越细,数据条数越多,但是膨胀不会太大 |
数据存储 | 单条数据大小 | ✅ 字段类型都是数值类型,每条数据的空间占用都不大 | ❌ 根据doris指标类型差异很大:数值类型的指标,空间占用不大bitmap类型的指标,如果hive表明细数据量非常大(例如流量数据),存储的bitmap会非常大 |
数据存储 | 总体数据量 | 数据量只跟条数有关系,也就是维度组合的多少&维度粒度粗细有关系(例子,商品多维分析,维度组合多且维度很细,所以存储的数据量非常大,导入出现过瓶颈) | 基本上受单条数据的大小影响更大,也就是指标类型的影响更大,如果指标都是bitmap类型,且hive底表数据量很大,那么doris的存储会很大(例子,流量多维分析,虽然每天的条数不多,但是占用的存储非常大,数据导入非常困难) |
数据存储 | 数据导入 | ❌ 使用唯一模型,导入字段都是数值类型,导入速度跟数据条数有关 | ❌ bitmap列越多越慢,主要体现在全局字典的构建和doris聚合数据的压力,以及bitmap的大小,目前平台的stream load和spark load两种方式对于bitmap的导入支持都不是很好 |
数据存储 | 数据计算 | ✅ 不需要聚合模型,唯一模型即可,不需要计算 | ❌ bitmap类型的指标多&hive表明细数据量非常大,会造成doris的聚合计算压力非常大,数据导入慢(例子,流量多维分析,bitmap非常大,数据导入load阶段压力非常大) |
数据查询 | 数据查询性能 | ✅ 查询性能很快,只需要select * | ❌ 查询性能跟数据量和指标类型关系很大,时间范围选的越长,查询时间增大明显 |
数据查询 | 数据查询组件 | 起源不支持,可以使用自建的cube冗余模型查询组件 | ✅ 直接使用起源的数据应用出数 |
数据查询 | 性能优化方案 | ✅ 基本上不需要优化,过慢的查询可以适当创建rollup | ❌ 必须要创建rollup,但是多维分析的维度组合太多,理论上需要创建的rollup非常多,但是需要考虑数据的导入性能,所以实际上rollup只能适当创建,性能优化比较困难 |
数据查询 | 查询复杂度 | ❌ 需要补充查询条件的维度之外的维度为-1,且需要考虑维度之间的级联关系,复杂度相对较高 | ✅ 只需要把查询条件和分组条件添加到sql中,其他的条件不需要关心 |
产品功能灵活性 | 鉴权 | ❌ 不能支持鉴权,包括事业部鉴权和品类鉴权事业部鉴权勉强还可以支持,但是只能限制用户选一个事业部,不能看有权限的全部事业部的汇总数据 | ✅ 可以支持 |
产品功能灵活性 | 自定义时间 | ❌ 不能支持自定义时间的聚合,只能支持固定的日周月、汇报周等 | ✅ 可以支持 |
流量多维分析案例
流量多维分析的数据导入和查询都出现了瓶颈
doris集群配置:
- FE3台:32G+16核
- BE5台:256G内存+64核 6T*12硬盘
doris表数据量:
- 维度数量:9个
- 指标数量:22个,bitmap指标21个
- 一天的数据条数:73823
- 表的总大小:1.864 TB(202010-202110,一年数据),副本数量3,bucket数量5
hive表数据量:
- 一天的数据量:75631702
doris数据导入任务:
- 一次导入4天的数据不会出错,导入时间范围超过4天,会出现load的时候异常
doris表数据查询:
- 查询2个月的数据会出现查询超时的情况,1个月偶尔也会
1. 冗余cube聚合结果模型
1.1 冗余cube聚合结果与起源
- 需要手动添加-1的条件:开发工作量较大,而且需要判断维度之间的层级关系,不如说用户查询某个具体的二级类目,没有指定一级类目,但是一级类目这个维度不能是-1
- 需要添加所有维度为group by列:对于查询性能有一定影响,尤其是维度比较多的情况下,指标也需要强行添加聚合函数
- 无法进行衍生计算:
- 类似于品类销售额占比这个指标,会配置一个衍生模型,依赖两个指标作为分子和分母
- 分母需要配置移除维度,也就是说,拼装sql的时候,起源会自动将用户提交的sql中的品类条件移除掉
但是对于冗余cube模型,移除类目条件是不够的,需要添加类目=-1的条件,这一点起源是做不到的- 起源通过支持grouping set和cube两种模型,并且支持维度的默认值设置,以及维度级联关系的设置,很好的支持了冗余cube模型的查询
1.2 起源对于冗余cube模型的支持
冗余cube模型这种叫法不是很规范,后续建议以起源的叫法为准,起源将模型的聚合类型分为三种:
- 普通:对模型包含的全部维度进行聚合查询
- groupingsets:对不同的维度组进行聚合预计算
- with cube:对维度组内任意的维度集合进行聚合预计算(仅支持创建一个维度组)
我们所说的冗余cube实际上对应的是grouping set和with cube这两种聚合类型,grouping set是with cube的子集。这两种数据聚合方式,是通过预计算的方式,将数据提前计算,各个维度组合的计算结果保存在一起,查询的时候不需要聚合,只需要简单的select。因为所有的聚合结果都存储在一起,所以被聚合的维度会给一个默认值,起源提供了维度粒度设置功能,可以给维度设置默认值。
同时,该功能会配合级联维度功能,级联的维度比如region/bu,如果bu设置了具体的值,即使用户没有设置region的值,也不会补充-1。
选择了冗余的这两种模型之后,指标计算方式的配置可以选择『无聚合方式』,此时产生的sql中不会有group by和sum等聚合函数。
2. 实时聚合的聚合模型
- doris导入压力很大,因为全局字典和导入的bitmap指标聚合计算,需求迭代重刷数据非常困难
- 聚合计算压力大,尤其是时间范围选的比较大,周月维度不能预聚合的场景