【零】Kylin的构建原理及简单优化

1. 维度和度量

  1. 维度即观察数据的角度。比如员工数据,可以从性别角度来分析,也可以更加细化,从入职时间或者地区的维度来观察。维度是一组离散的值,比如说性别中的男和女,或者时间维度上的每一个独立的日期。因此在统计时可以将维度值相同的记录聚合在一起,然后应用聚合函数做累加、平均、最大和最小值等聚合计算。
  2. 度量即被聚合(观察)的统计值,也就是聚合运算的结果。比如说员工数据中不同性别员工的人数,又或者说在同一年入职的员工有多少。

2. Cube和Cuboid

给定一个数据模型,我们可以对其上的所有维度进行聚合,对于N个维度来说,组合`的所有可能性共有2n种。对于每一种维度的组合,将度量值做聚合计算,然后将结果保存为一个物化视图,称为Cuboid。所有维度组合的Cuboid作为一个整体,称为Cube。
每一种维度组合就是一个Cuboid,16个Cuboid整体就是一个Cube。

【零】Kylin的构建原理及简单优化_第1张图片

3. 逐层构建算法(layer)

  1. 在逐层算法中,按维度数逐层减少来计算,每个层级的计算(除了第一层,它是从原始数据聚合而来),是基于它上一层级的结果来计算的。比如,[Group by A, B]的结果,可以基于[Group by A, B, C]的结果,通过去掉C后聚合得来的;这样可以减少重复计算;当 0维度Cuboid计算出来的时候,整个Cube的计算也就完成了。
  2. 每一轮的计算都是一个MapReduce任务,且串行执行;一个N维的Cube,至少需要N次MapReduce Job。

【零】Kylin的构建原理及简单优化_第2张图片

  1. 优点:充分利用了MapReduce的优点,处理了中间复杂的排序和shuffle工作,故而算法代码清晰简单,易于维护;受益于Hadoop的日趋成熟,此算法非常稳定,即便是集群资源紧张时,也能保证最终能够完成。
  2. 缺点:当Cube有比较多维度的时候,所需要的MapReduce任务也相应增加;由于Hadoop的任务调度需要耗费额外资源,特别是集群较庞大的时候,反复递交任务造成的额外开销会相当可观;由于Mapper逻辑中并未进行聚合操作,所以每轮MR的shuffle工作量都很大,导致效率低下。对HDFS的读写操作较多:由于每一层计算的输出会用做下一层计算的输入,这些Key-Value需要写到HDFS上;当所有计算都完成后,Kylin还需要额外的一轮任务将这些文件转成HBase的HFile格式,以导入到HBase中去;
  3. 总体而言,该算法的效率较低,尤其是当Cube维度数较大的时候。

4. 快速构建算法(inmem)

  1. 被称作“逐段”(By Segment) 或“逐块”(By Split) 算法,从1.5.x开始引入该算法,该算法的主要思想是,每个Mapper将其所分配到的数据块,计算成一个完整的小Cube 段(包含所有Cuboid)。每个Mapper将计算完的Cube段输出给Reducer做合并,生成大Cube,也就是最终结果。如图所示解释了此流程。
  2. 简单来说是基于内存的算法,在mapper中将相同的key聚合,不落盘 -> 将多个map结果输送到reduce 进行多个map的结果聚合

【零】Kylin的构建原理及简单优化_第3张图片

  1. Mapper会利用内存做预聚合,算出所有组合;Mapper输出的每个Key都是不同的,这样会减少输出到Hadoop MapReduce的数据量,Combiner也不再需要;
  2. 一轮MapReduce便会完成所有层次的计算,减少Hadoop任务的调配。

5. Cube存储原理

  1. 在计算之前,会为每一个维度建立一个维度字典表

【零】Kylin的构建原理及简单优化_第4张图片

  1. 在HBase中存储的K是Cuboid+纬度值,其中Cuboid是指参与的维度数量,1为参与,0为不参与;纬度值指是以十六进制存储的取自于维度字典表中所对应得值。

【零】Kylin的构建原理及简单优化_第5张图片

6. 使用衍生维度(derived dimension)

  1. 在kylin中属于构建优化,在选择维度表时有normal和derived,derived就是使用衍生维度。
  2. 加快了计算,减少了查询得速度
  3. 为了减少计算得cuboid
  4. 同一个维度表中,有选择derived时,不会真正参与构建,参与构建的是这个表对应事实表的外键
  5. 如果两者都存在,则有normal选normal,有derived 选择事实表主键
  6. 简单得来说,在维度表得字段选用了derived后,在进行预计算时,维度表得字段并不会真正参与,参与得是对应这个维度表中事实表得外键,查询时,用外键进行替换,最后进行聚合得到查询结果
  7. 最后尽量不要使用衍生维度

【零】Kylin的构建原理及简单优化_第6张图片

7. 使用聚合组(Aggregation group)

  1. 属于构建优化
  2. 聚合组(Aggregation Group)是一种强大的剪枝工具
  3. 分为三种:强制维度,层级维度,联合维度
  1. 强制维度(Mandatory): 除了带有A维度的cuboid,其他都会被过滤

【零】Kylin的构建原理及简单优化_第7张图片

  1. 层级维度(Hierarchy):B要依赖A才能存在,A能单独出现,B不可以

【零】Kylin的构建原理及简单优化_第8张图片

  1. 联合维度(Joint):AB维度,要么都存在,要么都不存在

【零】Kylin的构建原理及简单优化_第9张图片

  1. 以上构建优化操作可以在Cube Designer的Advanced Setting中的Aggregation Groups区域完成

【零】Kylin的构建原理及简单优化_第10张图片

8. Row Key优化

  1. Kylin会把所有的维度按照顺序组合成一个完整的Rowkey,并且按照这个Rowkey升序排列Cuboid中所有的行
  2. 设计良好的Rowkey将更有效地完成数据的查询过滤和定位,减少IO次数,提高查询速度,维度在rowkey中的次序,对查询性能有显著的影响。
  1. 被用作where过滤的维度放在前边。

【零】Kylin的构建原理及简单优化_第11张图片

  1. 基数大的维度放在基数小的维度前边。

【零】Kylin的构建原理及简单优化_第12张图片

9. 并发粒度优化

当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最少或最多被划分成多少个分区。

【零】Kylin的构建原理及简单优化_第13张图片

由于每个Cube的并发粒度控制不尽相同,因此建议在Cube Designer 的Configuration Overwrites(上图所示)中为每个Cube量身定制控制并发粒度的参数。假设将把当前Cube的kylin.hbase.region.count.min设置为2,kylin.hbase.region.count.max设置为100。这样无论Segment的大小如何变化,它的分区数量最小都不会低于2,最大都不会超过100。相应地,这个Segment背后的存储引擎(HBase)为了存储这个Segment,也不会使用小于两个或超过100个的分区。我们还调整了默认的kylin.hbase.region.cut,这样50GB的Segment基本上会被分配到50个分区,相比默认设置,我们的Cuboid可能最多会获得5倍的并发量。

10. 自动构建cube脚本

#!/bin/bash
cube_name=order_cube
do_date=`date -d '-1 day' +%F`

#获取00:00时间戳
start_date_unix=`date -d "$do_date 08:00:00" +%s`
start_date=$(($start_date_unix*1000))

#获取24:00的时间戳
stop_date=$(($start_date+86400000))

curl -X PUT -H "Authorization: Basic QURNSU46S1lMSU4=" -H 'Content-Type: application/json' -d '{"startTime":'$start_date', "endTime":'$stop_date', "buildType":"BUILD"}' http://hadoop102:7070/kylin/api/cubes/$cube_name/build

11. BI工具集成之JDBC

  1. 依赖
 <dependencies>
        <dependency>
            <groupId>org.apache.kylin</groupId>
            <artifactId>kylin-jdbc</artifactId>
            <version>2.5.1</version>
        </dependency>
    </dependencies>
  1. 编码
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));
        }
    }
}

  1. 结果

【零】Kylin的构建原理及简单优化_第14张图片

12. Life

当你越来越漂亮时,自然有人关注你。当你越来越有能力时,自然会有人看得起你。改变自己,你才有自信,梦想才会慢慢的实现。做最好的自己,懒可以毁掉一个人,勤可以激发一个人!
【零】Kylin的构建原理及简单优化_第15张图片

你可能感兴趣的:(零)