在代码中,cube build分为多个子任务:
- 创建宽表
- 创建词典
- 存储统计信息并设置cube build算法
- cube build,包括base-cuboid, N-1 cuboid,...,0 cuobid
- 更新metadata信息,并清理垃圾文件
public CubingJob build() {
logger.info("MR_V2 new job to BUILD segment " + seg);
final CubingJob result = CubingJob.createBuildJob(seg, submitter, config);
final String jobId = result.getId();
final String cuboidRootPath = getCuboidRootPath(jobId);
// 1. 创建宽表
inputSide.addStepPhase1_CreateFlatTable(result);
// 2. 构建词典
result.addTask(createFactDistinctColumnsStepWithStats(jobId)); // 维度列去重
result.addTask(createBuildDictionaryStep(jobId)); // 维度列编码
// 3. 存储统计信息并设置cube build算法
result.addTask(createSaveStatisticsStep(jobId)); // 用于判断使用哪一种cube build 方法
outputSide.addStepPhase2_BuildDictionary(result);
// 4. cube cuild
addLayerCubingSteps(result, jobId, cuboidRootPath); // layer cubing, only selected algorithm will execute
addInMemCubingSteps(result, jobId, cuboidRootPath); // inmem cubing, only selected algorithm will execute
outputSide.addStepPhase3_BuildCube(result);
// 5. 更新metadata信息,并清理垃圾文件
result.addTask(createUpdateCubeInfoAfterBuildStep(jobId));
inputSide.addStepPhase4_Cleanup(result);
outputSide.addStepPhase4_Cleanup(result);
return result;
}
创建宽表
根据表之间的关系,事实表与维度表做join操作,生成一张临时的宽表,包含有所有的数据。这一步只需要执行hive sql即可。
构建词典
基于临时的宽表,kylin首先构造了一个map reduce任务,对维度列去重。然后构造第二个MR任务,对去重后的维度列编码,构造一个字典,主要是为了减少hbase存储的数据量。实际使用的比较多的是前缀树,kylin将数字或字符串转换为字节数组后,再进行编码。
存储统计信息并设置cube build算法
可能会觉得奇怪,kylin在哪里进行了统计,统计了些什么? 其实,第二部,构建词典时,kylin使用了HyperLogLog算法,统计了每个cuboid需要的处理的行数,数据重复比例,也同时统计了构建base cuboid的时候使用的mapper数量。
管理员可以手动配置build算法——Inmem或Layer,也可以由kylin根据统计信息自动选择。当自动选择时,有一下判断标准:
- 如果用户选择的聚集方法是在统计时需要较多内存,那么选择Layer
2、如果build base cuboid的mapper数量超过限定值(默认500),并且数据重复比例超过限定值(默认7),则使用Inmem,否则仍然使用Layer。
cube build
kylin现在支持两种cube build算法:Inmem和Layer。
更新metedata信息并清理垃圾
kylin将build成功或失败的信息写入metadata中,并清理掉中间的数据。
网友评论