Kylin之Cube构建原理

目录

一、Cube构建流程

1.1、创建中间表

1.2、将中间表的数据均匀分配到不同的文件

1.3、创建维度字典表

1.4、多维度构建cube(重要)

1.5、Hbase K-V映射

1.6、将cube data转成HFile格式并导入HBase

二、Cube构建算法

2.1、逐层构建算法(layer)

2.2、快速构建算法(inmem)


一、Cube构建流程

1.1、创建中间表

1.2、将中间表的数据均匀分配到不同的文件

因为后面的程序是从中间表读取并运行mr程序的,如果你的中间表数据不均匀会造成后续的mr程序数据倾斜,降低效率。所以非常有必要将数据均匀分配。

我们来看看kylin到底是怎么均匀分配的。首先它会计算表中总共有多少行数据(total input rows),然后它默认每个文件1000000行数据(一百万行数据差不多不会超过hdfs一个块大小,也就是128M),然后计算有多少个文件(多少个reduce),total input rows/1000000。我们这里只有1个文件。然后设定reduce任务的个数,用distribute by重新将这些数据分配到不同的文件中。

1.3、创建维度字典表

比如job,可能有很多值,去重后,每个值按照0到N,一一映射保存到各个维度表中,这样做便于以后查询效率高,下面你就能感受到这种设计的巧妙之处了。

1.4、多维度构建cube(重要)

  • *代表无数据,也就是全体的意思。
  • 从一维到多维构建所有的情况,总共有2^n-1种情况,n表示维度。

1.5、Hbase K-V映射

按照步骤3,4一一构建映射。rowkey是由维度id+维度值组成的。比如第一行   java,2019-10-01,partA,10000这条数据,每一维都有数据,所以每一维都记1,就是111,然后对照步骤3,维度值是000,结果就是111000。再举个例子,比如第二行,c++ ,2019-05-01, * , 30000。只有前面两维有数据,所以是110,对照步骤3,维度值就是11,结果就是11011(注意,维度值是0就省略掉)。最终步骤4构建如下所示。(为了方便大家看,rowkey中写了‘+’,其实是没有‘+’)现在看看,数据全部都是数字存储,是不是简便了很多了。等会查询的时候你也会发现查询的效率也很高。

RowKey          value

111+000         10000

110+11           30000

100+2             200000

001+1             70000

1.6、将cube data转成HFile格式并导入HBase

步骤5的结果实际上是以sequence格式保存在hive中,现在将hive中结果导入HBase中。

二、Cube构建算法

2.1、逐层构建算法(layer)

我们知道,一个N维的Cube,是由1个N维子立方体、N个(N-1)维子立方体、N*(N-1)/2个(N-2)维子立方体、......、N个1维子立方体和1个0维子立方体构成,总共有2^N个子立方体组成,在逐层算法中,按维度数逐层减少来计算,每个层级的计算(除了第一层,它是从原始数据聚合而来),是基于它上一层级的结果来计算的。比如,[Group by A, B]的结果,可以基于[Group by A, B, C]的结果,通过去掉C后聚合得来的;这样可以减少重复计算;当 0维度Cuboid计算出来的时候,整个Cube的计算也就完成了。

每一轮的计算都是一个MapReduce任务,且串行执行;一个N维的Cube,至少需要N次MapReduce Job。

算法优点:
1)此算法充分利用了MapReduce的优点,处理了中间复杂的排序和shuffle工作,故而算法代码清晰简单,易于维护;
2)受益于Hadoop的日趋成熟,此算法非常稳定,即便是集群资源紧张时,也能保证最终能够完成。
算法缺点:
1)当Cube有比较多维度的时候,所需要的MapReduce任务也相应增加;由于Hadoop的任务调度需要耗费额外资源,特别是集群较庞大的时候,反复递交任务造成的额外开销会相当可观;
2)由于Mapper逻辑中并未进行聚合操作,所以每轮MR的shuffle工作量都很大,导致效率低下。
3)对HDFS的读写操作较多:由于每一层计算的输出会用做下一层计算的输入,这些Key-Value需要写到HDFS上;当所有计算都完成后,Kylin还需要额外的一轮任务将这些文件转成HBase的HFile格式,以导入到HBase中去;
总体而言,该算法的效率较低,尤其是当Cube维度数较大的时候。


2.2、快速构建算法(inmem)

也被称作“逐段”(By Segment) 或“逐块”(By Split) 算法,从1.5.x开始引入该算法,该算法的主要思想是,每个Mapper将其所分配到的数据块,计算成一个完整的小Cube 段(包含所有Cuboid)。每个Mapper将计算完的Cube段输出给Reducer做合并,生成大Cube,也就是最终结果。如图所示解释了此流程。

与旧算法相比,快速算法主要有两点不同:
1) Mapper会利用内存做预聚合,算出所有组合;Mapper输出的每个Key都是不同的,这样会减少输出到Hadoop MapReduce的数据量,Combiner也不再需要;
2)一轮MapReduce便会完成所有层次的计算,减少Hadoop任务的调配。

发布了430 篇原创文章 · 获赞 364 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/lixinkuan328/article/details/104254549