Kylin 是什么?
Apache Kylin™ 是一个开源的分布式分析引擎,提供 Hadoop/Spark 之上的SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由 eBay Inc. 开发并贡献至开源社区。能在亚秒内查询巨大的 Hive 表。
Kylin 是为减少在 Hadoop/Spark 上百亿规模数据查询延迟而设计,其核心思想是预计算 Cube,将数据按照指定的维度和指标,预先计算出所有可能的查询结果,利用空间换时间来加速查询模式固定的 OLAP 查询。
Kylin 基本架构
- Kyline 核心组件:REST Server 外部访问(提供 RESTful API、JDBC/ODBC 接口供用户调用)、Query Engine(查询引擎)、Routing(查询路由)、Cube Build Engine(Cube 构建引擎)、Metadata(元数据信息)
- 数据源:支持 Hadoop、Hive、Kafka、RDBMS
- Cube 存储:支持存储在 HBase(KV 数据库)
Kylin 中的数据流转
JobServer 负责将数据源的数据通过计算引擎构建生成 Cube 存储到 HBase 中;QueryServer 主要负责 SQL 的解析,逻辑计划的生成和优化,向 HBase 的多个 Region 发起请求,并对多个 Region 的结果进行汇总,生成最终的结果集。
Kylin 如何实现超大数据集的秒级多维分析查询
对于超大数据集的复杂查询,既然现场计算需要花费较长时间,那么根据空间换时间的原理,就可以提前将所有可能的计算结果计算并存储下来,从而实现超大数据集的秒级多维分析查询。
OLAP Cube
OLAP Cube 是一种典型的多维数据分析技术,Cube 本身可以认为是不同维度数据组成的 Dataset,一个 OLAP Cube 可以拥有多个维度(Dimension)以及多个事实(Factor Measure)。用户通过 OLAP 工具从多个角度来进行数据的多维分析。通常认为 OLAP 包括三种基本的分析操作:上卷(rollup)、下钻(drilldown)、切片切块(slicingand dicing),原始数据经过聚合以及整理后变成一个或多个维度的视图,这里不过多介绍。
Cube 由 Cuboid 组成,每个 Cuboid 可视为一种维度组合,并对应一组数据记录。所有的 Cuboid 组成 Cube,如下图所示:
Cuboid(A,B) 代表所有以 A,B 维度聚合的数据集
HBase
HBase 是分布式可扩展,针对海量数据的基于 Hadoop 的 KV 数据库。更多介绍
HBase 有以下特点,适合存储 Cube 数据集:
- 支持超大容量
- 支持 Rowkey 的范围查找
- 高性能、高吞吐、可扩展
- ...
Cuboid 的维度和指标如何转换为 HBase 的KV结构
简单的说 Cuboid + 维度会映射为 HBase 的 Rowkey,Cuboid 的指标会映射为 HBase 的 Value
Hive 原始表
两个维度:year、city,一个指标:price
year | city | price | … |
---|---|---|---|
1993 | BJ | 10 | |
1993 | BJ | 30 | |
1994 | SH | 20 | |
1994 | BJ | 40 |
维度组合
Cuboid 用8位表示
year | city | Cuboid |
---|---|---|
1993 | BJ | (year,city) => 00000000 |
1994 | SH | (year,city) => 00000000 |
1994 | BJ | (year,city) => 00000000 |
1993 | * | (year) => 00000001 |
1994 | * | (year) => 00000001 |
* | BJ | (city) => 00000010 |
* | SH | (city) => 00000010 |
* | * | () => 00000011 |
字典表
对维度值进行编码,主要为了节省存储,统一格式
维度值 | 编码 |
---|---|
1993 | 0 |
1994 | 1 |
BJ | 0 |
SH | 1 |
预聚合表
已知需要统计 sum(price)
指标,将所有维度组合(即4个 cuboid
)下的 sum(price)
指标计算出来,具体计算过程就是由指定的计算引擎完成的(MR / Spark)
year | city | sum(price) |
---|---|---|
1993 | BJ | 40 |
1994 | SH | 20 |
1994 | BJ | 40 |
1993 | * | 40 |
1994 | * | 60 |
* | BJ | 80 |
* | SH | 20 |
* | * | 100 |
转化为 HBase 中表
Rowkey 的具体格式是 cuboid id + 维度值
(新版本的 Rowkey 中为了并发查询还加入了 ShardKey)
Rowkey | Value | 解释 |
---|---|---|
00000000 | 100 | year(*)+ city(*) |
000000010 | 80 | year(*)+ city(BJ) |
000000011 | 20 | year(*)+ city(SH) |
000000100 | 40 | year(1993)+ city(*) |
000000101 | 60 | year(1994)+ city(*) |
0000001100 | 40 | year(1993)+ city(BJ) |
0000001110 | 40 | year(1994)+ city(BJ) |
0000001111 | 20 | year(1994)+ city(SH) |
所有的 cuboid 计算完成后,会将 cuboid 转化为 HBase 的KeyValue 格式生成 HBase 的 HFile,最后将 HFile load 进 cube 对应的 HBase 表中。
SQL 查询是如何转化为 HBase 的 Scan 操作的
假设查询SQL如下:
select year, sum(price) from table where city = "bj" group by year;
这个SQL涉及维度 year 和 city,所以其对应的 Cuboid 是 00000011,city的值是确定的 beijing(0),所以在Scan HBase时就会Scan Rowkey以 00000011 开头且 city 的值是 beijing 的行,取到对应指标 sum(price) 的值返回。
Cube 如何构建
创建 Cube 前,需定义一个数据模型(Model),Model 可以被多个 Cube 使用。
具体构建步骤参考官方文档:http://kylin.apache.org/cn/docs/tutorial/create_cube.html
Cube 计算方式
全量计算
每次从 hive 中读取全部数据进行构建,适用于两种情况:事实表不是按照时间增长的;事实表的数据量比较小或更新的频率很低,不会造成较大开销。
适用于两种情况:
事实表不是按照时间增长的;事实表的数据量比较小或更新的频率很低,不会造成较大开销。
增量计算
每次从 hive 中取出一个时间段 [Start Date,End Date) 的数据进行构建,并以一个 Segment 形式保存(一个 Segment 对应 HBase 中的一张表),下次构建时候自动以上次结束的时间为起点进行构建。增量构建的好处是避免了对历史数据进行重复计算。
Cube 计算算法
逐层算法
按维度数逐层减少计算(每一层数据基于上一层的结果聚合),算法简单、运行稳定、HDFS读写频繁
快速算法
分段并行计算(将数据分成多个段,每一段计算出完整的 Cube,最后 Merge),Mapper 预聚合,一次 MapReduce 完成计算、算法复杂,需要大量内存
Kylin 会自动选择合适的算法,估算出每个组合有多少不同的 key,计算出 Mapper 输出数据量,以及所有 Mapper 间数据的重合度来决定选择更优的。
Kylin 查询 SQL
Kylin 的查询引擎为 Calcite,其 SQL 语法参考:http://calcite.apache.org/docs/reference.html
References:
http://kylin.apache.org/cn/docs/
https://blog.bcmeng.com/post/apache-kylin-vs-baidu-palo.html
https://en.wikipedia.org/wiki/OLAP_cube