分布式分析引擎——Kylin

时光怂恿深爱的人放手 提交于 2020-01-07 01:15:45

【推荐】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

优点:

  1. 此算法充分利用了 MapReduce 的优点,处理了中间复杂的排序和 shuffle 工作,故而算法代码清晰简单,易于维护;
  2. 受益于 Hadoop 的日趋成熟,此算法非常稳定,即便是集群资源紧张时,也能保证最终能够完成。

缺点:

  1. Cube 有比较多维度的时候,所需要的 MapReduce 任务也相应增加;由于 Hadoop的任务调度需要耗费额外资源,特别是集群较庞大的时候,反复递交任务造成的额外开销会相当可观;
  2. 由于 Mapper 逻辑中并未进行聚合操作,所以每轮 MR shuffle 工作量都很大,导致效率低下。
  3. HDFS 的读写操作较多:由于每一层计算的输出会用做下一层计算的输入,这些Key-Value 需要写到 HDFS 上;当所有计算都完成后,Kylin 还需要额外的一轮任务将这些文件转成 HBase HFile 格式,以导入到 HBase 中去;
总体而言,该算法的效率较低,尤其是当 Cube 维度数较大的时候。

快速构建算法(inmem

每个 Mapper 将其所分配到的数据块,计算成一个完整的小 Cube 段(包含所有 Cuboid)。每个 Mapper 将计算完的 Cube 段输出给 Reducer 做合并,生成大 Cube,也就是最终结果。

与旧算法相比,快速算法主要有两点不同:
  1. Mapper 会利用内存做预聚合,算出所有组合;Mapper 输出的每个 Key 都是不同的,这样会减少输出到 Hadoop MapReduce 的数据量,Combiner 也不再需要;
  2. 一轮 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));
	}
	} 
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!