热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

kylin找不到hive_Kylin构建Cube过程详解

1前言在使用Kylin的时候,最重要的一步就是创建cube的模型定义,即指定度量和维度以及一些附加信息,然后对cube进行build&#x

eb92bec160935613a2b0c3dbde110169.gif

1 前言

在使用Kylin的时候,最重要的一步就是创建cube的模型定义,即指定度量和维度以及一些附加信息,然后对cube进行build,当然我们也可以根据原始表中的某一个string字段(这个字段的格式必须是日期格式,表示日期的含义)设定分区字段,这样一个cube就可以进行多次build,每一次的build会生成一个segment,每一个segment对应着一个时间区间的cube,这些segment的时间区间是连续并且不重合的,对于拥有多个segment的cube可以执行merge,相当于将一个时间区间内部的segment合并成一个。下面开始分析cube的build过程。

2 Cube示例

以手机销售为例,表SALE记录各手机品牌在各个国家,每年的销售情况。表PHONE是手机品牌,表COUNTRY是国家列表,两表通过外键与SALE表相关联。这三张表就构成星型模型,其中SALE是事实表,PHONE、COUNTRY是维度表。

3d94a4a5038146afcd321a6cc3d03344.png

现在需要知道各品牌手机于2010-2012年,在中国的总销量,那么查询sql为:

SELECT b.`name`, c.`NAME`, SUM(a.count)
FROM SALE AS a 
LEFT JOIN PHONE AS b ON a.`pId`=b.`id` 
LEFT JOIN COUNTRY AS c ON a.`cId`=c.`id` 
WHERE a.&#96;time&#96; >&#61; 2010 AND a.&#96;time&#96; <&#61; 2012 AND c.&#96;NAME&#96; &#61; "中国"
GROUP BY b.&#96;NAME&#96;

其中时间(time), 手机品牌(b.name&#xff0c;后文用phone代替)&#xff0c;国家(c.name&#xff0c;后文用country代替)是维度&#xff0c;而销售数量(a.count)是度量。手机品牌的个数可用于表示手机品牌列的基度。各手机品牌在各年各个国家的销量可作为一个cuboid&#xff0c;所有的cuboid组成一个cube&#xff0c;如下图所示&#xff1a;

03d24a9467ebf1232180fc4618817229.png

上图展示了有3个维度的cube&#xff0c;每个小立方体代表一个cuboid&#xff0c;其中存储的是度量列聚合后的结果&#xff0c;比如苹果在中国2010年的销量就是一个cuboid。

3    入口介绍

7c8cb6beac23e6e87ef5bd8f357a670d.png

在kylin的web页面上创建完成一个cube之后可以点击action下拉框执行build或者merge操作&#xff0c;这两个操作都会调用cube的rebuild接口&#xff0c;调用的参数包括&#xff1a;

1、cube名&#xff0c;用于唯一标识一个cube&#xff0c;在当前的kylin版本中cube名是全局唯一的&#xff0c;而不是每一个project下唯一的&#xff1b;
2、本次构建的startTime和endTime&#xff0c;这两个时间区间标识本次构建的segment的数据源只选择这个时间范围内的数据&#xff1b;对于BUILD操作而言&#xff0c;startTime是不需要的&#xff0c;因为它总是会选择最后一个segment的结束时间作为当前segment的起始时间。
3、buildType标识着操作的类型&#xff0c;可以是”BUILD”、”MERGE”和”REFRESH”。

4 构建Cube过程

Kylin中Cube的Build过程&#xff0c;是将所有的维度组合事先计算&#xff0c;存储于HBase中&#xff0c;以空间换时间&#xff0c;HTable对应的RowKey&#xff0c;就是各种维度组合&#xff0c;指标存在Column中&#xff0c;这样&#xff0c;将不同维度组合查询SQL&#xff0c;转换成基于RowKey的范围扫描&#xff0c;然后对指标进行汇总计算&#xff0c;以实现快速分析查询。整个过程如下图所示&#xff1a;

f10ff8f55d627fe2688d63768fdbb4e3.png

主要的步骤可以按照顺序分为几个阶段&#xff1a;
1、根据用户的cube信息计算出多个cuboid文件;
2、根据cuboid文件生成htable;
3、更新cube信息;
4、回收临时文件。
每一个阶段操作的输入都需要依赖于上一步的输出&#xff0c;所以这些操作全是顺序执行的。下面对这几个阶段的内容细分为11步具体讲解一下&#xff1a;

4.1 创建Hive事实表中间表(Create Intermediate Flat Hive Table)

这一步的操作会新创建一个hive外部表&#xff0c;然后再根据cube中定义的星状模型&#xff0c;查询出维度和度量的值插入到新创建的表中&#xff0c;这个表是一个外部表&#xff0c;表的数据文件(存储在HDFS)作为下一个子任务的输入。

4.2 重新分配中间表(Redistribute Flat Hive Table)

在前面步骤&#xff0c;hive会在HDFS文件夹中生成数据文件&#xff0c;一些文件非常大,一些有些小,甚至是空的。文件分布不平衡会导致随后的MR作业不平衡:一些mappers作业很快执行完毕&#xff0c;但其它的则非常缓慢。为了平衡作业&#xff0c;kylin增加这一步“重新分配”数据。首先&#xff0c;kylin获取到这中间表的行数,然后根据行数的数量,它会重新分配文件需要的数据量。默认情况下&#xff0c;kylin分配每100万行一个文件。

4.3 提取事实表不同列值 (Extract Fact Table Distinct Columns)

在这一步是根据上一步生成的hive中间表计算出每一个出现在事实表中的维度列的distinct值&#xff0c;并写入到文件中&#xff0c;它是启动一个MR任务完成的&#xff0c;它关联的表就是上一步创建的临时表&#xff0c;如果某一个维度列的distinct值比较大&#xff0c;那么可能导致MR任务执行过程中的OOM。

4.4 创建维度字典(Build Dimension Dictionary)

这一步是根据上一步生成的distinct column文件和维度表计算出所有维度的子典信息&#xff0c;并以字典树的方式压缩编码&#xff0c;生成维度字典&#xff0c;子典是为了节约存储而设计的。
每一个cuboid的成员是一个key-value形式存储在hbase中&#xff0c;key是维度成员的组合&#xff0c;但是一般情况下维度是一些字符串之类的值(例如商品名)&#xff0c;所以可以通过将每一个维度值转换成唯一整数而减少内存占用&#xff0c;在从hbase查找出对应的key之后再根据子典获取真正的成员值。

4.5 保存Cuboid的统计信息(Save Cuboid Statistics)

计算和统计所有的维度组合&#xff0c;并保存&#xff0c;其中&#xff0c;每一种维度组合&#xff0c;称为一个Cuboid。理论上来说&#xff0c;一个N维的Cube&#xff0c;便有2的N次方种维度组合&#xff0c;参考网上的一个例子&#xff0c;一个Cube包含time, item, location, supplier四个维度&#xff0c;那么组合(Cuboid)便有16种&#xff1a;

661c46293d8c67d74b802b7d675b9a16.png

4.6 创建HTable

创建一个HTable的时候还需要考虑一下几个事情&#xff1a;
1、列簇的设置。
2、每一个列簇的压缩方式。
3、部署coprocessor。
4、HTable中每一个region的大小。
在这一步中&#xff0c;列簇的设置是根据用户创建cube时候设置的&#xff0c;在HBase中存储的数据key是维度成员的组合&#xff0c;value是对应聚合函数的结果&#xff0c;列簇针对的是value的&#xff0c;一般情况下在创建cube的时候只会设置一个列簇&#xff0c;该列包含所有的聚合函数的结果&#xff1b;
在创建HTable时默认使用LZO压缩&#xff0c;如果不支持LZO则不进行压缩&#xff0c;在后面kylin的版本中支持更多的压缩方式&#xff1b;
kylin强依赖于HBase的coprocessor&#xff0c;所以需要在创建HTable为该表部署coprocessor&#xff0c;这个文件会首先上传到HBase所在的HDFS上&#xff0c;然后在表的元信息中关联&#xff0c;这一步很容易出现错误&#xff0c;例如coprocessor找不到了就会导致整个regionServer无法启动&#xff0c;所以需要特别小心&#xff1b;region的划分已经在上一步确定了&#xff0c;所以这里不存在动态扩展的情况&#xff0c;所以kylin创建HTable使用的接口如下&#xff1a;
public void createTable(final HTableDescriptor desc , byte [][] splitKeys)

4.7 用Spark引擎构建Cube(Build Cube with Spark)

在Kylin的Cube模型中&#xff0c;每一个cube是由多个cuboid组成的&#xff0c;理论上有N个普通维度的cube可以是由2的N次方个cuboid组成的&#xff0c;那么我们可以计算出最底层的cuboid&#xff0c;也就是包含全部维度的cuboid(相当于执行一个group by全部维度列的查询)&#xff0c;然后在根据最底层的cuboid一层一层的向上计算&#xff0c;直到计算出最顶层的cuboid(相当于执行了一个不带group by的查询)&#xff0c;其实这个阶段kylin的执行原理就是这个样子的&#xff0c;不过它需要将这些抽象成mapreduce模型&#xff0c;提交Spark作业执行。
使用Spark&#xff0c;生成每一种维度组合(Cuboid)的数据。
Build Base Cuboid Data&#xff1b;
Build N-Dimension Cuboid Data : 7-Dimension&#xff1b;
Build N-Dimension Cuboid Data : 6-Dimension&#xff1b;
……
Build N-Dimension Cuboid Data : 2-Dimension&#xff1b;
Build Cube。

4.8 将Cuboid数据转换成HFile(Convert Cuboid Data to HFile)

创建完了HTable之后一般会通过插入接口将数据插入到表中&#xff0c;但是由于cuboid中的数据量巨大&#xff0c;频繁的插入会对Hbase的性能有非常大的影响&#xff0c;所以kylin采取了首先将cuboid文件转换成HTable格式的Hfile文件&#xff0c;然后在通过bulkLoad的方式将文件和HTable进行关联&#xff0c;这样可以大大降低Hbase的负载&#xff0c;这个过程通过一个MR任务完成。

4.9 导HFile入HBase表(Load HFile to HBase Table)

将HFile文件load到HTable中&#xff0c;这一步完全依赖于HBase的工具。这一步完成之后&#xff0c;数据已经存储到HBase中了&#xff0c;key的格式由cuboid编号&#43;每一个成员在字典树的id组成&#xff0c;value可能保存在多个列组里&#xff0c;包含在原始数据中按照这几个成员进行GROUP BY计算出的度量的值。

4.10 更新Cube信息(Update Cube Info)

更新cube的状态&#xff0c;其中需要更新的包括cube是否可用、以及本次构建的数据统计&#xff0c;包括构建完成的时间&#xff0c;输入的record数目&#xff0c;输入数据的大小&#xff0c;保存到Hbase中数据的大小等&#xff0c;并将这些信息持久到元数据库中。

4.11 清理Hive中间表(Hive Cleanup)

这一步是否成功对正确性不会有任何影响&#xff0c;因为经过上一步之后这个segment就可以在这个cube中被查找到了&#xff0c;但是在整个执行过程中产生了很多的垃圾文件&#xff0c;其中包括&#xff1a;
1、临时的hive表&#xff1b;
2、因为hive表是一个外部表&#xff0c;存储该表的文件也需要额外删除&#xff1b;
3、fact distinct这一步将数据写入到HDFS上为建立子典做准备&#xff0c;这时候也可以删除了&#xff1b;
4、rowKey统计的时候会生成一个文件&#xff0c;此时可以删除&#xff1b;
5、生成HFile时文件存储的路径和hbase真正存储的路径不同&#xff0c;虽然load是一个remove操作&#xff0c;但是上层的目录还是存在的&#xff0c;也需要删除。

至此整个Build过程结束。




推荐阅读
  • MySQL多表数据库操作方法及子查询详解
    本文详细介绍了MySQL数据库的多表操作方法,包括增删改和单表查询,同时还解释了子查询的概念和用法。文章通过示例和步骤说明了如何进行数据的插入、删除和更新操作,以及如何执行单表查询和使用聚合函数进行统计。对于需要对MySQL数据库进行操作的读者来说,本文是一个非常实用的参考资料。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文介绍了在MySQL8.0中如何查看性能并解析SQL执行顺序。首先介绍了查询性能工具的开启方法,然后详细解析了SQL执行顺序中的每个步骤,包括from、on、join、where、group by、having、select distinct、union、order by和limit。同时还介绍了虚拟表的概念和生成过程。通过本文的解析,读者可以更好地理解MySQL8.0中的性能查看和SQL执行顺序。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • VueCLI多页分目录打包的步骤记录
    本文介绍了使用VueCLI进行多页分目录打包的步骤,包括页面目录结构、安装依赖、获取Vue CLI需要的多页对象等内容。同时还提供了自定义不同模块页面标题的方法。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
author-avatar
mobiledu2502900255
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有