Cube的使用包含创建和构建两个过程。
创建可以理解为“定义数据结构的过程”
构建可以理解为“往定义好的数据结构中添加计算数据的过程”
构建流程
以全量构建为例,Cube 的构建主要包含以下步骤,由构建引擎来调度执行:
Cube全量构件流程Step 1:创建 Hive 大平表
将创建 Cube 涉及到的维度从原有的事实表和维度表中查询出来组成一条完整的数据插入到一个新的 hive 表中
对链接
中举例的 Cube 进行构建,构建在 Kylin 页面上进行。
选择开始日期为 2012-01-01
,结束日期为 2012-08-01
,构建时执行如下命令:
hive -e "USE default;
DROP TABLE IF EXISTS kylin_intermediate_test_cube_44e5fcfe_e62f_375c_1e91_1d75d2fc6de3;
CREATE EXTERNAL TABLE IF NOT EXISTS kylin_intermediate_test_cube_44e5fcfe_e62f_375c_1e91_1d75d2fc6de3
(
KYLIN_SALES_PART_DT date
,KYLIN_SALES_LEAF_CATEG_ID bigint
,KYLIN_SALES_LSTG_SITE_ID int
,KYLIN_SALES_SLR_SEGMENT_CD smallint
,KYLIN_SALES_OPS_USER_ID string
,KYLIN_CAL_DT_CAL_DT date
,KYLIN_SALES_ITEM_COUNT bigint
,KYLIN_SALES_PRICE decimal(19,4)
)
STORED AS SEQUENCEFILE
LOCATION 'hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393
-d8ca-9dfd1b6a9bb9/kylin_intermediate_test_cube_44e5fcfe_e62f_375c_1e91_1d75d2fc6de3';
ALTER TABLE kylin_intermediate_test_cube_44e5fcfe_e62f_375c
_1e91_1d75d2fc6de3 SET TBLPROPERTIES('auto.purge'='true');
-- 根据数据模型定义的 join type 和 join condition 查询各个维度列并 insert 到 hive 表中
INSERT OVERWRITE TABLE kylin_intermediate_test_cube_44e5fcfe_e62f_375c_1e91_1d75d2fc6de3
SELECT
KYLIN_SALES.PART_DT as KYLIN_SALES_PART_DT
,KYLIN_SALES.LEAF_CATEG_ID as KYLIN_SALES_LEAF_CATEG_ID
,KYLIN_SALES.LSTG_SITE_ID as KYLIN_SALES_LSTG_SITE_ID
,KYLIN_SALES.SLR_SEGMENT_CD as KYLIN_SALES_SLR_SEGMENT_CD
,KYLIN_SALES.OPS_USER_ID as KYLIN_SALES_OPS_USER_ID
,KYLIN_CAL_DT.CAL_DT as KYLIN_CAL_DT_CAL_DT
,KYLIN_SALES.ITEM_COUNT as KYLIN_SALES_ITEM_COUNT
,KYLIN_SALES.PRICE as KYLIN_SALES_PRICE
FROM DEFAULT.KYLIN_SALES as KYLIN_SALES
INNER JOIN DEFAULT.KYLIN_CAL_DT as KYLIN_CAL_DT
ON KYLIN_SALES.PART_DT = KYLIN_CAL_DT.CAL_DT
WHERE (price > 0) AND (KYLIN_SALES.PART_DT >= '2012-01-01'
AND KYLIN_SALES.PART_DT < '2012-08-01')
;"
Step 2:构建字典
Kylin 使用字典编码(Dictionary-coder)对 Cube 中的维度值进行压缩:
- 纬度值 -> ID 及 ID -> 维度值。通过存储 ID 而不是实际值,Cube 的大小会显著减小
- ID 保留值的排序,加速了区间(range)查询
- 减少了内存和存储的占用
对于每一个维度列,都会写入两个文件:
- 维度列 distinct 值
- 字典文件
维度列 distinct 值文件:写出路径为 ${baseDir}/${colName}/${colName}.dci-r-${colIndex}
,如
hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/fact_distinct_columns/KYLIN_SALES.OPS_USER_ID/OPS_USER_ID.dci-r-00004
hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/fact_distinct_columns/KYLIN_SALES.SLR_SEGMENT_CD/SLR_SEGMENT_CD.dci-r-00003
hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/fact_distinct_columns/KYLIN_SALES.LEAF_CATEG_ID/LEAF_CATEG_ID.dci-r-00001
其内容为该维度列的所有 distinct 值,如:
$ hdfs dfs -cat hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/fact_distinct_columns/KYLIN_SALES.OPS_USER_ID/OPS_USER_ID.dci-r-00004
ADMIN
MODELER
$ hdfs dfs -cat hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/fact_distinct_columns/KYLIN_SALES.SLR_SEGMENT_CD/SLR_SEGMENT_CD.dci-r-00003
-99
16
$ hdfs dfs -cat hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/fact_distinct_columns/KYLIN_SALES.LEAF_CATEG_ID/LEAF_CATEG_ID.dci-r-00001
65
175750
字典文件:写入路径为 ${baseDir}/${colName}/${colName}.rldict-r-${colIndex}
,如:
hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/fact_distinct_columns/KYLIN_SALES.OPS_USER_ID/OPS_USER_ID.rldict-r-00004
hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/fact_distinct_columns/KYLIN_SALES.SLR_SEGMENT_CD/SLR_SEGMENT_CD.rldict-r-00003
hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/fact_distinct_columns/KYLIN_SALES.LEAF_CATEG_ID/LEAF_CATEG_ID.rldict-r-00001
Step 3:构建 Cube
使用逐层算法(Layer Cubing)
一个N维的Cube,是由:
- 1个N维子立方体
- N个(N-1)维子立方体
- N*(N-1)/2个(N-2)维子立方体
- (N-2)*(N-3)/2个(N-3)维子立方体
- ……
- N个1维子立方体
- 1个0维子立方体
构成,总共有2^N个 Cuboid 组成
在逐层算法中,按维度数逐层减少来计算,每个层级的计算(除了第一层,它是从原始数据聚合而来),是基于它上一层级的结果来计算的。
比如,[Group by A, B]的结果,可以基于[Group by A, B, C]的结果,通过去掉C后聚合得来的;这样可以减少重复计算。
当 0 维度 Cuboid 计算出来的时候,整个 Cube 的计算也就完成了
在介绍如何用 Spark 计算 Cube 之前,让我们看看 Kylin 如何用 MR 做到这一点;图1说明了如何使用经典的“逐层”算法计算四维立方体:第一轮 MR 从源数据聚合基础(4-D)立方体;第二个 MR 聚集在基本立方体上以获得三维立方体;使用 N + 1 轮 MR 计算所有层的立方体。
逐层构建
将一项大任务划分为几个步骤,每个步骤都基于前一步骤的输出,因此它可以重复使用先前的计算,并且还可以避免在两者之间出现故障时从头开始计算。这使它成为一种可靠的算法。
使用 Spark 逐层构建算法:
- 核心概念和逻辑与 MR 相同
-
区别在于将每层的立方体抽象为 RDD,然后使用父 RDD 生成子 RDD。尽可能在内存中缓存父 RDD 以获得更好的性能
image
我们可以在一个 Spark App 中组合所有 map-reduce 步骤;Spark 将生成 DAG 执行计划,然后自动运行它们。这样具有更少的调度开销。
使用 Spark相比于 MR 的耗时比较如下:
构建 Cube 的 Spark 任务如下:
Running org.apache.kylin.engine.spark.SparkCubingByLayer
-hiveTable default.kylin_intermediate_test_cube_44e5fcfe_e62f_375c_1e91_1d75d2fc6de3
-output hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/cuboid/
-input hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/kylin_intermediate_test_cube_44e5fcfe_e62f_375c_1e91_1d75d2fc6de3 -segmentId 44e5fcfe-e62f-375c-1e91-1d75d2fc6de3
-metaUrl kylin_metadata@hdfs,path=hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/metadata
-cubename test_cube
如下为生成的各级维度的 Cuboid 文件:
$ hdfs dfs -ls hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/cuboid/
drwxr-xr-x - root supergroup 0 2019-04-17 08:26 hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/cuboid/level_1_cuboid
drwxr-xr-x - root supergroup 0 2019-04-17 08:26 hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/cuboid/level_2_cuboid
drwxr-xr-x - root supergroup 0 2019-04-17 08:26 hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/cuboid/level_3_cuboid
drwxr-xr-x - root supergroup 0 2019-04-17 08:26 hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/cuboid/level_4_cuboid
drwxr-xr-x - root supergroup 0 2019-04-17 08:26 hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/cuboid/level_5_cuboid
drwxr-xr-x - root supergroup 0 2019-04-17 08:26 hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/cuboid/level_base_cuboid
Step 4:将 Cuboid 数据转化为 HFile 文件(By Spark)
一个转换任务的例子如下;
Running org.apache.kylin.storage.hbase.steps.SparkCubeHFile
-partitions hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/rowkey_stats/part-r-00000_hfile
-counterOutput hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/counter
-cubename test_cube -output hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/hfile
-input hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/cuboid/
-segmentId 44e5fcfe-e62f-375c-1e91-1d75d2fc6de3
-metaUrl kylin_metadata@hdfs,path=hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/metadata
-hbaseConfPath hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/hbase-conf.xml
Step 5: 将 HFile 文件 load 到 HBase 表中
Version:1.0 StartHTML:0000000100 EndHTML:0000000444 StartFragment:0000000100 EndFragment:0000000444
-input hdfs://localhost:9000/kylin/kylin_metadata/kylin-f7a8f547-4312-2393-d8ca-9dfd1b6a9bb9/test_cube/hfile -htablename KYLIN_ABHS9OKHZA -cubename test_cube
如下是一个 Cuboid 在 HBase 表中的形式
网友评论