Kylin原理详解

1. 基本介绍

1.1 Kylin简介

Kylin就是一个解决TB级别数据的数据分析需求的系统,通过预计算方式缓存了所有需要查询的数据结果,需要大量的存储空间。

1.2 为什么出现

首先需要明确OLAP和OLTP的概念。

简单来说OLTP(联机事务处理过程) 是面向交易过程的,特点就是需要即时处理。OLAP(联机分析处理) 支持复杂分析操作,侧重于对决策的支持,要求快速的对大数据量进行查询分析。

其中OLAP有三种实现方式

  • ROLAP(基于关系数据库):多维数据库的多维结构划分为两类表:一类是事实表,存储数据维度关键字,另一类是维度表,就是对维度的层次,成员等维度描述信息。事实表和维度表就构成了星型模型,聚合后的数据也保存在关系型的数据库中,但是查询效率也很低。
  • MOLAP(基于多维数据):使用多维数组存储数据。多维数据在存储中形成Cube结构,特点就是将细节数据和聚合后的数据均保存在Cube中空间换时间,查询效率高。
  • HOLAP(基于混合数据):底层是关系型,高层是多维矩阵型,比较灵活。特点是细节保存在关系型数据库中,聚合后的数据保存在Cube中。

Kylin就是MOLAP的实现。

1.3 Kylin主要功能

Kylin的核心功能就是构建Cube。

之前我们说过MOLAP是空间换时间,Kylin通过预计算来缓存所有需要查询的结果,并且将结果构建成Cube存储在HBase中,用户查询时就可以做到秒/亚秒级查询。

2. 原理

2.1 整体架构

Apache官方直接给了我们Kylin的架构图。

image

从上往下依次来看

  • REST Server:提供一些restfule接口,例如创建、构建、刷新、合并等对cube的操作,project、table、cube等元数据管理、用户访问权限、系统配置动态修改等,REST Server还提供了JDBC/ODBC的驱动,使得我们在程序中很好的使用,另外我们可以看到通过该接口可以使用SQL查询,对我们编写提供了很大的方便。
  • Query Engine:Kylin使用开源的Calcite框架实现上面的SQL的解析,相当于SQL引擎层
  • Routing:负责解析SQL生成的执行计划转换成cube的缓存的查询,查询分为两部分,一部分直接查询HBase中已经缓存的cube,另一部分则要直接查询原始数据(Hadoop的HDFS上通过Hive查询),这个部分延迟相对较高。
  • Metadata元数据引擎,Kylin有很多的元数据信息,包括cube定义、星型模型定义、job和job的执行信息、模型的维度信息等,这些元数据和cube都存储在HBase中,存储格式是json字符串。
  • Cube Build Engine:核心模块,构建cube引擎,负责Kylin预计算中创建cube。

2.1 构建Cube

Kylin的所有模块的基础就是构建cube然后将它存储。

扫描二维码关注公众号,回复: 6731126 查看本文章

cube大致的创建过程是先通过Hive读取原始数据,然后通过Hadoop的MapReduce或者Spark框架计算生成Htable(HBase的数据格式)。

Layer Cubing(逐层计算)
按照dimension(维度)数量从大到小的顺序(从下往上),从Base Cuboid开始,依次基于上一层的Cuboid的结构进行再聚合。每一层的计算都是一个单独的MapReduce任务
图中假设我们要计算四个维度的cube,第一轮,读取原始数据的RawData,去掉不相关的列,同时对维度列进行压缩编码,这里就是计算出图中的4-D Cuboid(4个维度即所有维度),也就是base cuboid
此后的每一轮,输入都是上一轮的输出,也就是重用之前的计算结构,去掉要聚合的维度,算出新的Cuboid,直到算出所有的维度组合的Cuboid。
image

MapReduce的计算结果最终会保存到HBase中,HBase中每行记录的Rowkey由dimention组成,measure会保存在Column family中。

基本流程概括如下

  1. 根据star图,调用Hive,创建一张宽表(指标、维度、属性的关联起来的字段较多的数据库表)
  2. 对宽表中的维度列去重,存到hdfs中
  3. 为去重后的维度列建词典
  4. 读取宽表数据,计算base cuboid
  5. 基于base cuboid,计算次级cuboid
  6. 将cuboid批量导入HBase中

2.2 Cube优化

主要有两方面优化

  • 提出聚合组的概念,去除不必要的维度组合,加速构建。
  • 宽表数据重新分配,避免数据倾斜

聚合组比较常用也比较重要,它就是将维度分组,不同聚合组内的维度之间不会计算cuboid,举个例子,假如分成1,2两组,a在1组,b在2组,Kylin在构建时不会把a和b组合到一起,因为它们在不同的组。

但是如果在查询的时候需要跨聚合组查询,那么Kylin需要更大的代价。

聚合组内又有三种优化方式

  • 强制维度(Mandatroy Dimensions):每次查询都会携带的维度
  • 层次维度(Hierarchy Dimensions):具有层次关系的维度组成一个Hierarchy,例如年、月、日。如果不设置Hierarchy,会有六个cuboid,如果设置了,就会增加一个cuboid约束,低的Dimension一定会随高的出现,也就是我们不可以查询group by mouth,day。
  • 联合维度(Joint Dimensions):会统一出现的查询维度。cuboid要么都不包含这些维度,要么包含所有维度。

至于数据重新分配,Kylin对宽表会执行再分配策略,调用Hive的Distribute by,如果配置了shard by,会按照列的值来重新划分数据位置,否则随机。

2.3 Sql查询

Cube构建完成之后,就可以查询维度对应的度量值了

查询的时候,SQL语句被SQL解析器翻译成一个解析计划,从这个计划可以准确知道用户要查哪些表,怎样join起来,有哪些过滤条件。Kylin用这个计划去匹配找寻到合适的Cube,如果有Cube命中,这个计划会发送到存储引擎,翻译成对存储引擎(一般为HBase)相应的Scan操作。

并且它有自己的一套映射规则

  • table=>cube
  • group,colunm=>cuboid id
  • group,where=>Row Key(HBase的Key)
  • aggreations=>Row Value(HBase的相应Key的Value)

最后将cube值转换为sql查询结果样式返回给用户。

至于Kylin的使用,可以看Apache的官方文档,写的很清楚。

猜你喜欢

转载自blog.csdn.net/MoForest/article/details/91465373
今日推荐