【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
Apache Kylin 是一个开源的分布式分析引擎,提供 Hadoop/Spark 之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由 eBay 开发并贡献至开源社区。它能在亚秒内查询巨大的 Hive 表。
Cube构建流程
- 创建中间表
- 将中间表的数据均匀分配到不同的文件(防止数据倾斜)
- 创建字典表
- 构建cube
- 形成HBase的K-V结构
- 将cube data转化成Hfile格式并导入HBase
Cube构建算法
逐层构建算法(layer)(中心开花)
每个层级的计算是基于它上一层级的结果来计算的。
每一轮的计算都是一个
MapReduce
任务,且串行执行;一个
N
维的
Cube
,至少需要
N 次 MapReduce Job
。
优点:
- 此算法充分利用了 MapReduce 的优点,处理了中间复杂的排序和 shuffle 工作,故而算法代码清晰简单,易于维护;
- 受益于 Hadoop 的日趋成熟,此算法非常稳定,即便是集群资源紧张时,也能保证最终能够完成。
缺点:
- 当 Cube 有比较多维度的时候,所需要的 MapReduce 任务也相应增加;由于 Hadoop的任务调度需要耗费额外资源,特别是集群较庞大的时候,反复递交任务造成的额外开销会相当可观;
- 由于 Mapper 逻辑中并未进行聚合操作,所以每轮 MR 的 shuffle 工作量都很大,导致效率低下。
- 对 HDFS 的读写操作较多:由于每一层计算的输出会用做下一层计算的输入,这些Key-Value 需要写到 HDFS 上;当所有计算都完成后,Kylin 还需要额外的一轮任务将这些文件转成 HBase 的 HFile 格式,以导入到 HBase 中去;
总体而言,该算法的效率较低,尤其是当
Cube
维度数较大的时候。
快速构建算法(inmem)
每个 Mapper 将其所分配到的数据块,计算成一个完整的小 Cube 段(包含所有 Cuboid)。每个 Mapper 将计算完的 Cube 段输出给 Reducer 做合并,生成大 Cube,也就是最终结果。
与旧算法相比,快速算法主要有两点不同:
- Mapper 会利用内存做预聚合,算出所有组合;Mapper 输出的每个 Key 都是不同的,这样会减少输出到 Hadoop MapReduce 的数据量,Combiner 也不再需要;
- 一轮 MapReduce 便会完成所有层次的计算,减少 Hadoop 任务的调配。
Cube构建优化
在kylin中,有 n 个维度,就会构建 2ⁿ-1 个Cube,因此在构建维度数量较多时,会造成构建引擎、存储引擎的巨大压力。要注意 Cube 的剪枝优化(既减少Cube的生成)
使用衍生维度
使用聚合组
强制维度
层级维度
联合维度
Row key的优化
Kylin 会把所有的维度按照顺序组合成一个完整的
Rowkey
,并且
按照这个 Rowke 升序排列 Cuboid 中所有的行
。设计良好的 Rowkey
将更有效地完成数据的查询过虑和定位,减少
IO
次数,提高查询速度,维度在 rowkey
中的次序,对查询性能有显著的影响。
被用作 where 过滤的维度放在前边
基数大的维度放在基数小的维度前边
并发粒度优化
当
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
(默认为
1
)和
kylin.hbase.region.count.max
(默认为
500
)两个配置来决定每个
Segment
最少或最多被划分成多少个分区。
增量表的构建
Model 模型指定分区字段
构建 cube 指定合并的规则
kylin的JDBC
//添加依赖
<dependencies>
<dependency>
<groupId>org.apache.kylin</groupId>
<artifactId>kylin-jdbc</artifactId>
<version>2.5.1</version>
</dependency>
</dependencies>
//代码
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));
}
}
}
来源:oschina
链接:https://my.oschina.net/u/4427158/blog/3151546