1. 概述
kylin 是 OLAP 引擎,采用多维立方体预计算技术,可将大数据的 SQL 查询速度提升到亚秒级别。
需求:
虽然像 spark,hive 等使用 MPP 大规模并行处理和列式存储的方式,可以将 Hadoop 的 SQL查询提高到了分钟级别,
但是仍然不能满足数据分析师的要求。在面对超大规模的数据集时,分析师不要讲更多的精力花在等待查询结果上,
而不是更加重要的建立领域模型上。
kylin 就是要打破查询时间随着数据量成线性增长的规律,采用的思路就是 “预计算”
它会尽量的预先计算聚合结果,在查询时刻尽量的使用预算的结果得出查询结果,从而避免直接扫描可能无限增长的原始记录。
预计算是 Kylin 在大规模并行处理和列式存储外,提供给大数据分析的第 3 个关键技术。
工作原理
kylin 的工作原理本质上是多维立方体分析 MOLAP multidimensional online analytical processing cube.
在讲解工作原理前,涉及到维度 dimension 和度量 measure 的概念。
维度就是观察数据的角度。
度量就是被聚合的统计值,也是聚合运算的结果,一般是连续的值。
根据维度和度量可以得到下面做预计算的 Cube 理论
给定一个数据模型,可以对其上的所有维度进行组合。对于 N 个维度来说,组合的可能性就有 2^n 种。
对每种维度的组合,将度量做聚合运算,然后将运算的结果保存为一个物化视图,叫做 Cuboid。所有维度组合的 Cuboid 作为一个整体,就称为 Cube。
kylin 的工作原理就是对数据模型做 Cube 预计算,并利用计算的结果加速查询,具体工作过程如下
1) 指定数据模型,定义维度和度量
2)预计算 Cube,计算所有 Cuboid 并保存为物化视图
3)执行查询时,读取 Cuboid,运算产生查询结果
kylin 的查询过程不会扫描原始记录,而是通过预计算预先完成表的关联,聚合等复杂运算,并利用预计算的结果来执行查询。
技术架构
kylin 分为在线查询和离线构建两个部分。
先看下离线构建的部分,数据源在左侧,保存着待分析的用户数据。根据元数据的定义,下方构建引擎从数据源
抽取数据,并构建 Cube。数据以关系表的形式输入,且必须符合星形模型 start schema。 MapReduce 是当前
主要的构建技术,构建后的 Cube 保存在右侧的存储引擎中,一般选用 HBase 作为存储。
完成了离线构建,用户可以从上方查询系统发送 SQL进行查询分析。 Kylin 提供了各种 Rest API,JDBC/ODBC 接口。
无论哪个接口进入, SQL最终会来到 Rest 服务层,再转交给查询引擎进行处理。
主要特点
1. 标准 SQL接口,kylin 以标准 SQL 作为对外服务的主要接口
2. 支持超大数据集
3. 亚秒级响应
4. 可伸缩性和高吞吐率
5. BI 及可视化工具集成
2.快速入门
核心概念
数据仓库 Data Warehouse 简写 dw
OLAP online analytical process 联机分析处理,以多维度的方式分析数据,而且能够弹性的提供上卷,下钻,透视分析等操作
BI business intelligence :商务智能,指用现代数据仓库技术,在线分析技术,数据挖掘和数据展现技术进行数据分析以实现商业价值。
维度和度量 在上一章已经介绍
事实表 fact table: 存储有事实记录的表,如系统日志,销售记录等;事实表的记录在不断的动态增长,所以其体积通常远大于其他表。
维度表或维表,是与事实表相对应的一种表,是与事实表相对应的一种表,它保存了维度的属性值,可以跟事实表做关联;
相当于将事实表上经常重复出现的属性抽取,规范出来用一张表进行管理。常见的维度表有:日期表,地点表等。
使用维度表的好处
- 缩小了事实表的大小
- 便于维度的管理和维护
- 可以为多个事实表重用,以减少重复工作
Cube,Cuboid 和 Cube Segment
Cube 也称为 Data Cube 叫做数据立方体,是一种常用于数据分析与索引的技术,可以对原始数据建立多维度索引。
通过 Cube 对数据进行分析,可以大大加快数据的查询效率。
Cuboid 在 kylin 中特指在某一种维度组合下所计算的数据。
Cube Segment 是指针对源数据中的某一个片段,计算出来的 Cube 数据。
在 hive 中准备数据
kylin 要分析的数据必须要先保存为 Hive 表的形式,然后 kylin 才能从 Hive 中导入数据,创建 Cube。
星形模型 star schema
星形模型中有一张事实表,以及 0 个或多个维度表;事实表与维度表通过主键外键关联,维度表之间没有关联,就像很多星星围绕
在一个恒星周围,因此取名为星形模型。
如果将星形模型中的某些维度的表再做规范,抽取成更细的维度表,然后让维度表之间也进行关联,那么这种模型称为雪花模型。
维度表的设计
kylin 对维度表的要求如下
1) 要有数据一致性,主键必须是唯一的;kylin 会进行检查,如果有两行的主键值相同就会报错
2) 维度表越小越好,因为 kylin 会将维度表加载到内存中供查询,过大的表不适合做维度表,默认阈值是 300M
3) 改变频率低, kylin 会在每次构建中试图重用维度表的快照,如果维度表经常改变的话,重用就会失效,但每次都需要将视图进行物化
4) 维度表最好不要是 Hive 视图
Hive 表分区
Hive 表支持多分区 partition。 简单的说,一个分区就是一个文件目录,存储了特定的数据文件。当有新的数据生成的时候,
可以将数据加载到指定的分区,读取数据的时候也可以指定分区。对于 SQL 查询,如果查询中指定了分区列的属性条件,则
Hive 会智能的选择特定分区(也就是目录),从而避免全量数据的扫描,减少读写操作对集群的压力。
kylin 支持增量的 Cube 构建,通常会按照时间属性增量的从 Hive 中抽取数据。 如果 Hive 表正好是按照时间属性进行分区,
就可以在每次 Hive 构建的时候直接跳过不相干日期的数据,节省 Cube 构建的时间。
这样的列在 Kylin 里也称为分隔时间列 Partition Time Column, 通常也应该是 Hive 表的分区列。
维度的基数
维度的基数是指该维度在数据集中出现的不同值的个数。
如果基数超过 100 万的维度通常称为高基数维度 UHC ultra high cardinality 就需要引起设计者的注意。
计算基数有多种途径,最简单的方法就是让 Hive 执行一个 count distinct 的SQL 查询。
设计 Cube
导入 Hive 定义
这里说的是将 Hive 表的定义导入到 Kylin 中。
单击 Web 界面的 Model -> Datasource 下的 Load Hive Table 图标,输入表的名称,单击 sync,
kylin 就会使用 Hive 的API 从 Hive 中获取表的属性信息。
导入成功后, Kylin 就会在后台触发一个 MapReduce 任务,计算此表每个列的基数。
创建数据模型
数据模型是 Cube 的基础,主要用于描述一个星形模型,有了数据模型后,定义 Cube 的时候就可以直接从此模型定义的表和列中进行选择了,
省去了重复指定 join 的步骤。基于一个数据模型还可以创建多个 Cube,以方便减少用户的重复性工作。
点击 Models 页面,单击 New -> New Model,开始创建数据模型。给模型输入名称后,选择一个事实表(必须的),然后添加维度表
(可选的)。
接下来选择会用作维度和度量的列。此处只是选择一个范围,不代表这些列将来一定要用作 Cube 的维度或者度量,
后续创建 cube时,将只能从这些列进行选择。
选择维度列时,维度可以来自事实表或者维度表。
选择度量列时,度量只能来自事实表。
最后一步,是为模型补充分隔时间列信息和过滤条件。如果此模型中的事实表记录是按照时间增长的,那么可以指定一个日期/时间
作为模型的分隔时间列,从而可以让 Cube 按照此列做增量构建。
Filter 过滤条件是指,如果想把一些记录忽略掉,就可以设置一个过滤条件。 kylin 在想 Hive 请求源数据时,会带上此过滤条件。
最后,单击 Save 保存此数据模型,随后,它将出现在 Models 的列表中。
创建 Cube
点击 New 选择 New Cube 就会开启创建 Cube 的向导。
第一页,选择要使用的数据模型,并为此 Cube 输入一个唯一的名称(必需的)和描述(可选的)
这里还可以输入一个邮件通知列表,用于在构建完成或出错时收到通知。 Notification Events 中将其去掉。
第二页, 选择 Cube 的维度
第三页, 创建度量。Kylin 默认会创建一个 Count(1) 的度量,可以单击 "+Measure" 按钮来添加新的度量
第四页,是关于 Cube 数据刷新的设置。在这里可以设置自动合并的阈值,数据保留的最短时间
第五页,高级设置,此页面可以设置聚合组和 RowKey
kylin 默认会把所有维度都放在一个聚合组中,如果维度较多,可以将维度分为多个聚合组。通过使用聚合组,
可以大大降低 Cube 中的 Cuboid 数量。
Mandatory 维度是指那些总是会出现在 where 条件或者 Group By 语句里的维度;
通过将某个维度指定为 Mandatory, Kylin 就可以不用预计算那些不包含此维度的 Cuboid,从而减少计算量。
Hierachy 是一组有层次关系的维度,通过指定 Hierarchy Kylin 就可以省略不满足此模式的 Cuboid
Joint Dimensions 是将多个维度组合成一个维度,通常适用于如下两种情形
- 总是在一起查询的维度
- 基数很低的维度
kylin 会以 key-value 的方式将 Cube 存储到 Hbase 中。 Hbase 的 key,就是 Rowkey, 是由各个维度的值拼接
而成的。在存储时, kylin 会对他们进行编码和压缩,每个维度可以选择合适的编码(Encoding) 方式,默认采用
字典 dictionary 编码技术,除了字典外,还有整数 Int 和固定长度 Fixed Length 的编码。
编码的选取规则在另一篇文章中说明。
第六页,为 Cube 配置参数。
Kylin 使用了很多配置参数以提高灵活性,用户根据具体的环境,场景等配置不同的参数进行调优。
Kylin 全局的参数可在 conf/kylin.properties 文件中进行配置,如果 Cube 要覆盖全局配置,则需要在此页面指定。
构建 Cube
新创建的 Cube 只有定义,没有计算的数据,其状态是 Disabled。要想 Cube 有数据,还需要对其进行构建。
Cube 的构建通常有两种:全量构建和增量构建。包含下面步骤
1. 创建临时的 Hive 平表
2. 计算各维度的不同值,并收集 Cuboid 的统计数据
3. 创建并保存字典
4. 保存 Cuboid 统计信息
5. 创建 HTable
6. 计算 Cube
7. 将 Cube 的计算结果转成 HFile
8. 加载 HFile 到 HBase
9. 更新 Cube 元数据
10. 垃圾回收
第 9 步完成后,会将此次构建的 Segment 的状态从 New 更新为 READY,表示已经可供查询了。
全量构建和增量构建
全量构建
对数据模型中没有指定分割时间列信息的 Cube, Kylin 会采用全量构建,即每次从 Hive 中读取全部的数据来开始构建。
通常适用于下面两种情况:
1. 事实表的数据不是按照时间增长的
2. 事实表的数据比较小或者更新频率很低,全量构建不会造成太大的开销
增量构建
增量构建的时候,kylin 每次都会从 Hive 中读取一个时间范围内的数据,然后进行计算,并以一个 Segment 的形式保存。
下次再构建时,会自动以上次结束的时间为起点时间,再选择新的终止时间进行构建。经过多次构建, Cube 中将会有
多个 Segment 依次按照时间进行排列。
使用增量构建的好处是,每次只需要对新增数据进行计算,从而避免了对历史数据进行重复计算。对数据量很大的 Cube,
使用增量构架非常有必要。
合并
Cube 可能会存在较多数量的 Segment, 使查询性能下降,并且会给 HBase 集群管理带来压力。对此,需要适时的将一些
Segment 进行合并,将若干个 Segment 合并成较大的 Segment。
查询 Cube
Cube 构建好后,状态变为 READY,就可以进行查询了。
Kylin 的查询语言是标准的 SQL 的 SELECT 语言,这是为了获得与大多数 BI 系统和工具无缝集成的可能性。
SQL 参考如下
1. Kylin 作为 OLAP 引擎,只支持查询,而不支持其他操作,如 update, insert 等,也就是说所有的 SQL 都必须是
SELECT 语句,否则 kylin 会报错
2. 查询 Kylin 中 SQL 语句的表名,列名,度量,连接关系时,需要至少跟一个 Cube 的模型匹配
3. Kylin 使用 Apache Calcite 做 SQL 语法分析,它是一个开源的 SQL 引擎,提供了标准的 SQL 解析,多查询优化
和连接各种数据源的能力