yyK## 1 Kylin 概述
1.1 Kylin定义
Apache Kylin 是一个开源的分布式分析引擎,提供 Hadoop/Spark 之上的 SQL 查询接口及多维分析(MOLAP)能力以支持超大规模数据,它能在亚秒内查询巨大的 Hive 表。
1.2 术语解释
Data Warehouse(数据仓库):数据仓库是一个各种数据(包括历史数据和当前数据)的中心存储系统,是BI( business intelligence ,商业智能)的核心部件
Business Intelligence(商业智能):商业智能通常被理解为将企业中现有的数据转化为知识,帮助企业做出明智的业务经营决策的工具
OLAP(online analytical processing):OLAP(online analytical processing)是一种软件技术,它使分析人员能够迅速、一致、交互地从各个方面观察信息,以达到深入理解数据的目的,从各方面观察信息,也就是从不同的维度分析数据,因此 OLAP 也成为多维分析
image image星型模型:
image事实和维度:
image image1.3 架构
image1、REST Server:是一套面向应用程序开发的入口点,旨在实现针对 Kylin 平台的应用开发工作,此类应用程序可以提供查询、获取结果、触发 Cube 构建任务、获取元数据以及获取用户权限等等,另外可以通过 Restful 接口实现 SQL 查询
2、查询引擎(Query Engine):当 Cube 准备就绪后,查询引擎就能够获取并解析用户查询,它随后会与系统中的其它组件进行交互,从而向用户返回对应的结果
3、路由器(Routing):在最初设计时曾考虑过将 Kylin 不能执行的查询引导去 Hive 中继续执行,但在实践后发现 Hive与 Kylin 的速度差异过大,导致用户无法对查询的速度有一致的期望,很可能大多数查询几秒内就返回结果了,而有些查询则要等几分钟到几十分钟,因此体验非常糟糕,最后这个路由功能在发行版中默认关闭
4、元数据管理工具(Metadata):Kylin 是一款元数据驱动型应用程序,元数据管理工具是一大关键性组件,用于对保存在 Kylin 当中的所有元数据进行管理,其中包括最为重要的 Cube 元数据,其它全部组件的正常运作都需以元数据管理工具为基础,Kylin 的元数据存储在 HBase 中
5、任务引擎(Cube Build Engine):这套引擎的设计目的在于处理所有离线任务,其中包括 shell 脚本、Java API、MR 等,任务引擎对 Kylin 当中的全部任务加以管理与协调,从而确保每一项任务都能得到切实执行并解决其间出现的故障
1.4 特点
-
标准 SQL 接口:Kylin 是以标准的 SQL 作为对外服务的接口
-
支持超大数据集:Kylin 对于大数据的支撑能力可能是目前所有技术中最为领先的
-
亚秒级响应:Kylin 拥有优异的查询相应速度,这点得益于预计算,很多复杂的计算,比如连接、聚合,在离线的预计算过程中就已经完成,这大大降低了查询时刻所需的计算量,提高了响应速度
-
可伸缩性和高吞吐率:单节点 Kylin 可实现每秒 70 个查询,还可以搭建 Kylin 的集群
-
BI 工具集成
-
ODBC:与 Tableau、Excel、PowerBI 等工具集成
-
JDBC:与 Saiku、BIRT 等 Java 工具集成
-
RestAPI:与 JavaScript、Web 网页集成
-
Zepplin:访问 Kylin 服务
-
2 安装部署
1、先决条件是必须安装 hadoop、hive、hbase、zookeeper
2、需要在 /etc/profile 文件中配置 HADOOP_HOME、HIVE_HOME、HBASE_HOME、并 source 使其生效
3、解压 apache-kylin-2.5.1-bin-hbase1x.tar.gz到 /opt/module
<pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="bash" cid="n210" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 0px; width: inherit; color: rgb(184, 191, 198); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> [djm@hadoop102 sorfware]$ tar -zxvf apache-kylin-2.5.1-bin-hbase1x.tar.gz -C /opt/module/</pre>
4、启动和关闭
<pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="bash" cid="n212" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 0px; width: inherit; color: rgb(184, 191, 198); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> [djm@hadoop102 kylin] bin/kylin.sh stop</pre>
5、测试
username:ADMIN
password:KYLIN
3 快速入门
3.1 创建项目
image image3.2 创建 Model
image image image image image image image image image3.3 创建 Cube
image image image image image image高阶模块(默认)
image image image4 Cube 构建原理
4.1 构建流程
image image image image image image4.2 构建算法
4.2.1 逐层构建算法
image一个 n 维的立方体由 2^(n-1) 个立方体组成,在逐层算法中,按维度逐层减少来计算,每个层级的计算都是基于其上一层的结果来计算的,当 0 层维度被计算出来的时候,整个 Cube 的计算就完成了
每一轮的计算都是一个 MapReduce 任务,且串行执行,n 维的 Cube,至少需要 n 次 MapReduce Job
算法优点:
-
充分利用了 MapReduce 的优点,处理了中间复杂的排序和 shuffle 工作,代码清晰简单,易于维护
-
受益于 Hadoop 的日趋成熟,此算法非常稳定,即便是集群资源紧张时,也能保证最终能够完成
算法缺点:
-
当 Cube 有比较多维度的时候,所需要的 MapReduce 任务也相应增加
-
由于 Hadoop 的任务调度需要耗费额外资源,特别是集群较庞大的时候,反复递交任务造成的额外开销会相当可观
-
由于 Mapper 逻辑中并未进行聚合操作,所以每轮 MR 的 shuffle 工作量都很大,导致效率低下
-
对 HDFS 的读写操作较多,由于每一层计算的输出会用做下一层计算的输入,这些 KV 需要写到 HDFS 上,当所有计算都完成后,Kylin 还需要额外的一轮任务将这些文件转成 HBase 的 HFile 格式,以导入到 HBase 中
4.2.2 快速构建算法
image也被称作逐段(By Segment)或逐块(By Split)算法,从 1.5.x 开始引入该算法,该算法的主要思想是,每个 Mapper 将其所分配到的数据块,计算成一个完整的小 Cube 段(包含所有 Cuboid),每个 Mapper 将计算完的 Cube 段输出给Reducer 做合并,生成大 Cube,也就是最终结果
image与旧算法相比,快速算法主要有两点不同:
- Mapper 会利用内存做预聚合,算出所有组合,Mapper 输出的每个Key 都是不同的,这样会减少输出到 Hadoop MapReduce 的数据量,Combiner 也不再需要
2)一轮 MapReduce 便会完成所有层次的计算,减少 Hadoop 任务的调配
5 Cube 构建优化
在没有采取任何优化措施的情况下,Kylin 会对每一种维度的组合进行预计算,每种维度的组合的预计算结果被称为Cuboid,假设有4个维度,我们最终会有 16 个 Cuboid 需要计算。
但在现实情况中,用户的维度数量一般远远大于 4 个,假设用户有 10 个维度,那么没有经过任何优化的 Cube 就会存在1024 个 Cuboid,而如果用户有 20 个维度,那么Cube 中总共会存在 1048576 个 Cuboid,虽然每个 Cuboid 的大小存在很大的差异,但是单单想到 Cuboid 的数量就足以让人想象到这样的 Cube 对构建引擎、存储引擎来说压力有多么巨大,因此,在构建维度数量较多的 Cube 时,尤其要注意 Cube 的优化。
5.1 衍生维度
衍生维度用于在有效维度内将维度表上的非主键维度排除掉,并使用维度表的主键(其实是事实表上相应的外键)来替代它们,Kylin 会在底层记录维度表主键与维度表其他维度之间的映射关系,以便在查询时能够动态地将维度表的主键翻译成这些非主键维度,并进行实时聚合。
虽然衍生维度具有非常大的吸引力,但是也不是说所有的维度表都适合衍生维度,如果从维度主建到某个维度的聚合工作量较大,不建议使用,时间换空间还是空间换时间,看业务需求权衡。
image5.2 聚合组
5.2.1 强制维度
如果一个维度被定义为强制维度,那么整个分组中产生的 cubeid 必须包含该维度,每个分组中都可以有 0 个或多个强制维度。如果根据这个分组的业务逻辑,则相关的查询一定会在过滤条件或分组条件中,因此可以在该分组中把该维度设置为强制维度。
image5.2.2 层级维度
每个层级中包含两个或多个维度,假设 D1、D2 被设置为层级维度,那么分组中的 cubeid 如果 D2 出现时,D1 必须也出现,但是 D1 可以单独出现,一般适用于日期、地址,每个分组中可以有0个、1个或多个层级,不同的层级之间不应当有共享的维度。如果根据这个分组的业务逻辑,则多个维度直接存在层级关系,因此可以在该分组中把这些维度设置为层级维度。
image5.2.3 联合维度
每个联合维度包含两个或多个维度,如果某些列形成一个联合,那么在该分组产生的任何 Cuboid 中,这些联合维度要么一起出现,要么都不出现,每个分组中可以有 0 个或多个联合,但是不同的联合之间不应当有共享的维度(否则它们可以合并成一个联合),如果根据这个分组的业务逻辑,多个维度在查询中总是同时出现,则可以在该分组中把这些维度设置为联合维度。
image这些操作可以在 Cube Designer 的 Advanced Setting 中的 Aggregation Groups 区域完成
5.3 RowKey 优化
Kylin 会把所有的维度按照顺序组合成一个完整的 RowKey,并且按照这个 RowKey 升序排列 Cuboid 中所有的行,设计良好的 RowKey 将更有效地完成数据的查询过滤和定位,减少 IO 次数,提高查询速度,维度在 RowKey 中的次序,对查询性能有显著的影响。
RowKey 的设计原则如下:
-
被用作 where 过滤的维度放在前边
-
基数大的维度放在基数小的维度前边
5.4 并发粒度优化
当 Segment 中某一个 Cuboid 的大小超出一定的阈值时,系统会将该 Cuboid 的数据分片到多个分区中,以实现 Cuboid数据读取的并行化,从而优化 Cube 的查询速度,具体的实现方式如下:
构建引擎根据 Segment 估计的大小,以及参数 kylin.hbase.region.cut 的设置决定 Segment 在存储引擎中总共需要几个分区来存储,如果存储引擎是 HBase,那么分区的数量就对应于 HBase 中的 Region 数量,kylin.hbase.region.cut 的默认值是 5.0,单位是 GB,也就是说对于一个大小估计是 50GB 的 Segment,构建引擎会给它分配 10 个分区,用户还可以通过设置 kylin.hbase.region.count.min、kylin.hbase.region.count.max 来决定每个 Segment 最少或最多被划分成多少个分区
由于每个 Cube 的并发粒度控制不尽相同,因此建议在 Cube Designer 的 Configuration Overwrites 中为每个 Cube 量身定制控制并发粒度的参数,假设将把当前 Cube 的 kylin.hbase.region.count.min 设置为 2,kylin.hbase.region.count.max设置为 100,这样无论 Segment 的大小如何变化,它的分区数量最小都不会低于 2,最大都不会超过 100,相应地,HBase 为了存储这个 Segment,也不会使用小于两个或超过 100 个的分区,我们还调整了默认的kylin.hbase.region.cut,这样 50GB 的 Segment 基本上会被分配到50个分区,相比默认设置,我们的 Cuboid可能最多会获得 5 倍的并发量
6 集成 BI 工具
6.1 JDBC
导入依赖:
<pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="xml" cid="n312" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 0px; width: inherit; color: rgb(184, 191, 198); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> <dependencies>
<dependency>
<groupId>org.apache.kylin</groupId>
<artifactId>kylin-jdbc</artifactId>
<version>2.5.1</version>
</dependency>
</dependencies></pre>
编码:
<pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="java" cid="n314" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 0px; width: inherit; color: rgb(184, 191, 198); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> package com.djm;
import java.sql.*;
public class TestKylin {
public static void main(String[] args) throws Exception {
//Kylin_JDBC 驱动
String KYLIN_DRIVER = "org.apache.kylin.jdbc.Driver";
//Kylin_URL
String KYLIN_URL = "jdbc:kylin://hadoop102:7070/FirstProject";
//Kylin的用户名
String KYLIN_USER = "ADMIN";
//Kylin的密码
String KYLIN_PASSWD = "KYLIN";
//添加驱动信息
Class.forName(KYLIN_DRIVER);
//获取连接
Connection connection = DriverManager.getConnection(KYLIN_URL, KYLIN_USER, KYLIN_PASSWD);
//预编译SQL
PreparedStatement ps = connection.prepareStatement("SELECT sum(sal) FROM emp group by deptno");
//执行查询
ResultSet resultSet = ps.executeQuery();
//遍历打印
while (resultSet.next()) {
System.out.println(resultSet.getInt(1));
}
}
}</pre>
6.2 Zepplin
1、解压 zeppelin-0.8.0-bin-all.tgz 到 /opt/module
<pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="bash" cid="n317" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 0px; width: inherit; color: rgb(184, 191, 198); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> [djm@hadoop102 sorfware]$ tar -zxvf zeppelin-0.8.0-bin-all.tgz -C /opt/module/</pre>
2、修改文件夹名称
<pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="bash" cid="n319" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 0px; width: inherit; color: rgb(184, 191, 198); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> [djm@hadoop102 module]$ mv zeppelin-0.8.0-bin-all/ zeppelin</pre>
3、启动
<pre spellcheck="false" class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" lang="bash" cid="n321" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; margin-top: 0px; margin-bottom: 20px; background: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 0px; width: inherit; color: rgb(184, 191, 198); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> [djm@hadoop102 zeppelin]$ bin/zeppelin-daemon.sh start</pre>
4、访问
网友评论