Kylin初涉

来源:互联网 发布:linux视频服务器搭建 编辑:程序博客网 时间:2024/06/05 11:33

概述

Kylin是一个开源的分布式分析引擎,提供Hadoop之上的SQL查询接口及多维分析能力以支持超大规模数据,可以在亚秒内查询巨大的Hive表

与其他引擎对比:

Hive、Impala、Presto、Spark-Sql等查询时间是与数据量成正比,数据量非常大的时候,查询性能就下降了。时间复杂度O(N)

Kylin:查询时间与数据量无关。时间复杂度O(1)


基本概念

Cube:不同维度的聚合形成的集合

下图是由维度时间(Time)、商品(Item)、地点(Location)和供应商(Supplier)构成的cube。

 

每一种组合称为一个Cuboid,例如[Time,Item]是一个Cuboid


Kylin原理 

1.建立数据模型,定义维度和度量

2.预计算Cube,将所有的Cuboid保存为物化视图

3.执行查询,读取Cuboid,运算,产生查询结果

比如:

Select Time,location,count(1) from table  group by Time ,location

维度Time和Location的聚合,在Cube构建的时候已经计算了,所以在线查询时可以直接读取计算好的Cuboid。而类似Hive、Impala等需要在运行的时候,再去对维度进行聚合,所以时间也就慢了。


Cube构建 

逐层构建算法

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

 

下图为一个四维Cube的构建过程:

此算法的Mapper和Reducer都比较简单。Mapper以上一层Cuboid的结果(Key-Value对)作为输入。由于Key是由各维度值拼接在一起,从其中找出要聚合的维度,去掉它的值成新的Key,然后把新Key和Value输出,进而HadoopMapReduce对所有新Key进行排序、洗牌(shuffle)、再送到Reducer处;Reducer的输入会是一组有相同Key的Value集合,对这些Value做聚合计算,再结合Key输出就完成了一轮计算。

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

 

问题:

对HDFS的读写操作较多;Cube有比较多维度的时候,所需要的MapReduce任务也相应增加; 该算法的效率较低

 

 

快速构建算法(逐块构建算法)

该算法的主要思想是,对Mapper所分配的数据块,将它计算成一个完整的小Cube 段(包含所有Cuboid);每个Mapper将计算完的Cube段输出给Reducer做合并,生成大Cube,也就是最终结果;如下图所示:

 

 

 

 

Cube构建流程

Cube的构建包含如下步骤,由任务引擎来调度执行。
1)创建临时的Hive平表(从Hive读取数据)。
2)计算各维度的不同值,并收集各Cuboid的统计数据。
3)创建并保存字典。
4)保存Cuboid统计信息。
5)创建HTable。
6)计算Cube(一轮或若干轮MapReduce)。

7)将Cube的计算结果转成HFile。
8)加载HFile到HBase。(RowKey为:Cuboid ID + 维度值,Value为度量值)
9)更新Cube元数据。(变更Cube状态)
10)垃圾回收。(删除临时表)

 

Kylin架构

分为离线构建和在线查询

离线构建:

数据源为Hive/Kafka,MR构建Cube,构建好之后存入HBase

在线查询:

可以直接在Kylin的界面中用Sql查询,或调用相关接口(Kylin提供了Rest API、JDBC/ODBC接口),查询引擎解析Sql,然后将其转译为基于Cube的物理执行计划,最后查询预计算生成的cube并生成结果。整个过程不会访问数据源

 

 其他Cube优化

全量构建与增量构建

全量构建

对数据模型中没有指定分割时间列信息的Cube,Kylin会采用全量构建,即每次从Hive中读取全部的数据来开始构建。通常它适用于以下两种情形。
事实表的数据不是按时间增长的。
事实表的数据比较小或更新频率很低,全量构建不会造成太大的开销。

 

增量构建

Kylin每次都会从Hive中读取一个时间范围内的数据,然后进行计算,并以一个Segment的形式进行保存。下次再构建的时候,会自动以上次结束的时间为起点时间,再选择新的终止时间进行构建。经过多次构建,Cube中将会有多个Segment依次按时间顺序进行排列,如Seg-1,Seg-2,…,Seg-N。查询的时候,Kylin会查询一个或多个Segment然后再做聚合计算,以便返回正确的结果给请求者。
使用增量构建的好处是,每次只需要对新增数据进行计算,从而避免了对历史数据进行重复计算。对于数据量很大的Cube,使用增量构建是非常有必要

 

增量构建引发的问题

历史数据刷新

Cube构建完成以后,如果某些历史数据发生了改动,那么需要针对相应的Segment进行重新计算,这种构建称为刷新。刷新通常只针对增量构建的Cube而言,因为全量构建的Cube只要重新全部构建就可以得到更新;而增量更新的Cube因为有多个Segment,因此需要先选择要刷新的Segment,然后再进行刷新。

在刷新的同时,Cube仍然可以被查询,只不过返回的是陈旧数据。当Segment刷新完毕时,新的Segment会立即生效,查询开始返回最新的数据。老Segment则成为垃圾,等待回收。

Cube合并

随着时间的迁移,Cube中可能会存在较多数量的Segment,使得查询性能下降,并且会给HBase集群管理带来压力。对此,需要适时地将一些Segment进行合并,将若干个小Segment合并成较大的Segment。

合并的好处具体如下:

1)合并相同的Key,从而减少Cube的存储空间。

2)由于Segment减少了,因此可以减少查询时的二次聚合,提高了查询性能。

3)HTable的数量得以减少,更便于集群的管理。

 

 

 

 

维度爆炸

随着维度数目的增加Cuboid的数量会爆炸式地增长:

假设用户有4个维度,我们可能最终会有2^4 =16Cuboid需要计算。

假设用户有10个维度,那么没有经过任何优化的Cube就会存在2^10=1024Cuboid;而如果用户有20个维度,那么Cube中总共会存在2^20=1048576Cuboid

 

不仅占用大量的存储空间还会延长Cube的构建时间。为了缓解Cube的构建压力,减少生成的Cuboid数目,ApacheKylin引入了一系列的高级设置,帮助用户筛选出真正需要的Cuboid

 

聚合组(Aggregation Group):

可筛选出自己关注的维度组合,将其划分为一个聚合组,聚合组可有多个。

 

 

 

强制维度(Mandatory):每个Cuboid都必须包含的维度(每次查询都会用到的维度),比如Date。Kylin在预计算时,可排除没有此维度的cuboid,节省计算

 

层次维度(Hierarchy):为带层级的dimension,比如说:省份->城市, 年->季度->月->周->日。后面的维度会依赖前面的维度,

比如,一般为 group by 年,季度,月、group by 年,月……

但很少为 group by 季度,月   group by 月……,即可过滤这部分维度组合

 

联合维度(Joint):

每个联合中包括两个或多个维度组合,在每个Cuboid中,这些联合要么都出现,要么都不出现


参考

http://www.infoq.com/cn/articles/apache-kylin-algorithm/(Cube构建算法)

http://blog.csdn.net/skyyws/article/details/54923630(Cube构建过程)

http://download.csdn.net/download/u014307117/10027489 (Apache Kylin 权威指南)

http://www.chinahadoop.cn/course/765Apache Kylin的原理,架构和典型案例



原创粉丝点击