kylin 教程与原理

官方教程请参考:http://kylin.apache.org/cn/

参考文章:https://www.cnblogs.com/honey01/p/8351145.html

总结:

kylin是一个olap引擎

(1)首先kylin从先建立一个model(包括维度,度量,及join的方式,时间列的选择用于根据时间段查询)

时间列的格式有规定 

(2)然后创建cube,创建cube的流程如下:

(3)cobe包括多个cobeid,每个cobeid为一组维度的组合

(4)他只是从数据源抽取数据,然后根据 事先设置好的维度进行维度组合(默认为全维度,可以根据维度规则进行剪枝优化防止维度爆炸),然后根据统计(sum,count,max等)的度量算好在每一个维度的值,存入hbase,把维度组合作为rowkey,统计类型+字段名作为列族或者列,把统计值作为value来进行存储。使用select查询时,就只能使用预先构建好的cube中存在的统计方法及字段进行查询,这样查询的数据就是hbase中的数据,所有的cube都存在hbase,查询时会把 sql语言转换为hbase查询语言,注意这里的sql 不是完全和mysql或者oracle的sql完全相同,具体的sql中的方法请参考官方教程http://kylin.apache.org/cn/docs/tutorial/sql_reference.html

(5)select的字段只能是cube中存在的维度,或者sum(a),max(a)等,不能是单个度量字段如:select a from xx,注意a表示度量字段

(6)关于 group by,order by,where 条件或者分组语句后面跟的字段必须是cube中设置好的维度,或者 select max(a) as a_max中的a_max。不能是单个度量字段如 where a>10,会报错,hbase中没有这个关系或者字段,所以预先设置cube的时候必须要针对某个特定场景进行设置,不能要求通用多个场景

(7)关于维度爆炸,如果有3个维度,默认的全维度为2的3次方=8种组合,若不进行维度则会产生维度爆炸

(8)关于超基数维,若一个维度有100万种以上不相同的数据,则称为超基数维度,超基数维度会导致hbase的rowkey成倍增长

(9)关于实际中遇到的问题,查询select count(*) from table1,结果为1000条,但是查询select * from table1只有5条?原因如下:

kylin默认有一个度量count,所以查询count的时候定位到某个列族-列,此列的值就是数据源的总的记录数(预先计算好的)

而select * from table1则是查询的group by 所有的维度。

(10)如何同时作为维度,又是度量?

 在cube的创建度量的时候,选择 also show dimensions就会显示所有度量

(11)最后生成的维度,可通过以下方式查看,可以看到生成了三个维度,鼠标放上去可以看到当前维度的组成

关于维度在hbase中的存储及各种维度的构建,以及优化防止维度爆炸的方法请参考以下:

 

维度优化

为什么需要维度优化

因为如果不进行任何维度优化,直接将所有的维度放在一个聚集组里,Kylin就会计算所有的维度组合(cuboid)。

比如,有12个维度,Kylin就会计算2的12次方即4096个cuboid,实际上查询可能用到的cuboid不到1000个,甚至更少。 如果对维度不进行优化,会造成集群计算和存储资源的浪费,也会影响cube的build时间和查询性能,所以我们需要进行cube的维度优化。

当你在保存cube时遇到下面的异常信息时,意味1个聚集组的维度组合数已经大于 4096 ,你就必须进行维度优化了。

image_1aufkne841pr4155d15bh1cmigf09.png-43.3kB

如何计算1个聚集组的维度组合数

当有层次维度时,公式如下:
(hierarchy.size() + 1) * hierarchyDimsList.size() * (1 << jointDimsList.size()) * (1 << normalDims.size())

当没有层次维度时,公式如下:
1 << jointDimsList.size()) * (1 << normalDims.size()


hierarchyDimsList.size(): 层次维度的个数。
hierarchy.size(): 每个层次维度包含的维度个数。
jointDimsList.size(): 联合维度的个数。
normalDims.size(): 正常维度的个数,即不是强制维度,层次维度,联合维度的维度数目。

如何进行维度优化

首先请确认你设置的cube维度都是你查询时会使用到的。

目前Kylin可以使用的维度优化手段有以下几种:

  • 聚集组
  • 衍生纬度
  • 强制维度
  • 层次维度
  • 联合维度
  • Extended Column

下文会详细介绍以上维度优化手段的基本概念,以及何时使用这些优化手段。

聚集组

聚集组:用来控制哪些cuboid需要计算。

适用场景:不是只需要计算base cuboid的情况下,都需要聚集组。

注意事项:一个维度可以出现在多个聚集组中,但是build期间只会计算一次。

如果不设置聚集组,默认情况下只会计算 base cuboid

聚集组不宜太多。

衍生维度

衍生维度:维表中可以由主键推导出值的列可以作为衍⽣维度。

使用场景:以星型模型接入时。例如用户维表可以从userid推导出用户的姓名,年龄,性别。

优化效果:维度表的N个维度组合成的cuboid个数会从2的N次方降为2。

图示: 此处输入图片的描述

强制维度

强制维度:所有cuboid必须包含的维度,不会计算不包含强制维度的cuboid。

适用场景:可以将确定在查询时一定会使用的维度设为强制维度。例如,时间维度。

优化效果:将一个维度设为强制维度,则cuboid个数直接减半。

图示: 强制维度

层次维度

层次维度:具有一定层次关系的维度。

使用场景:像年,月,日;国家,省份,城市这类具有层次关系的维度。

优化效果:将N个维度设置为层次维度,则这N个维度组合成的cuboid个数会从2的N次方减少到N+1。

图示: 此处输入图片的描述

联合维度

联合维度:将几个维度视为一个维度。

适用场景: 1 可以将确定在查询时一定会同时使用的几个维度设为一个联合维度。

2 可以将基数很小的几个维度设为一个联合维度。

3 可以将查询时很少使用的几个维度设为一个联合维度。

优化效果:将N个维度设置为联合维度,则这N个维度组合成的cuboid个数会从2的N次方减少到1。

Extended Column

在OLAP分析场景中,经常存在对某个id进行过滤,但查询结果要展示为name的情况,比如user_id和user_name。这类问题通常有三种解决方式:

a. 将ID和Name都设置为维度,查询语句类似select name, count(*) from table where id = 1 group by id,name。这种方式的问题是会导致维度增多,导致预计算结果膨胀;

b. 将id和name都设置为维度,并且将两者设置为联合。这种方式的好处是保持维度组合数不会增加,但限制了维度的其它优化,比如ID不能再被设置为强制维度或者层次维度;

c. 将ID设置为维度,Name设置为特殊的Measure,类型为Extended Column。这种方式既能保证过滤id且查询name的需求,同时也不影响id维度的进一步优化。

所以此类需求我们推荐使用 Extended Column。

HBase Rowkey顺序

简单的讲,查询频率越高的维度在Rowkey中的顺序需要越靠前。

 

 

cube在hbase中的存储

全维度构建

假设一张表有3个字段name,age,sex,那么当通过kylin构建这张表的cube时,hbase的表结构如下所示。注意本示例没有度量字段,value表示记录条数累计,代表count(*),度量如果存在那么也是存储在value的位置,可以手动配置cf。

通过图1很明显的可以看到,kylin将每个维度的所有基数都枚举了出来,并通过组合的方式构建出hbase的rowkey,另外将组合对应的记录数做预统计保存在value中,对应hbase表中的一个cf:c。

  

 

当维度基数很大的时候,那么构建cube会称为灾难,所以kylin提供了cube的组合模式来减少cube的总维度组合。这里相关概念可以参考《kylin介绍》,下面直接对不同的模式进行案例分析。

 

aggregate group

意思是多少几个维度可以任一组合

假设图1中的cube配置aggregate group为2,那么构建出的cube相比全维度组合构建剪去了3个维度组合的部分,参数图2

 

mandatory

假设图1中的维度name是必要维度,那么构建出的hbase结构参考图3

 

joint

假设图1中name和sex维度是joint关系,那么构建出的hbase结构如图4

 

Hierarchy

继承关系比较好理解,这里就不展示了: )

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章