麒麟Kylin

 

 开源的分布式分析引擎,提供Hadoop/Spark之上的SQL查询接口及多维分析(MOLAP)能力以支持超大规模数据,能在亚秒内查询巨大的Hive表;linux

Kylin的主要特色包括支持SQL接口、支持超大规模数据集、亚秒级响应、可伸缩性、高吞吐率、BI工具集成等。web

MR Hive
M(多维)OLAP链接分析处理的引擎
Hive--->Kylin--->Hbase算法

1.  Kylin架构

 第一部分:sql

Metadata(元数据)和Cube Build Engine构建引擎(作分析运算),离线-提早算-预计算apache

第二部分:对外查询(实时)输出:
REST Server(接收请求)-->
Query Engine(sql语法解析)
Routing(链接HBase)windows

须要调用使用的场景:架构

  第三方App REST-API-->基于http协议
  BI tools:Tableau..企业级商业智能-可视化界面-->基于jdbc、ODBC(windows/ linux)app

2. Kylin工做原理

 本质上是MOLAP(Multidimension On-Line Analysis Processing)Cube,也就是多维立方体分析;分布式

Kylin的工做原理就是对数据模型作Cube预计算,并利用计算的结果加速查询:ide

1)指定数据模型,定义维度和度量;

2)预计算Cube,计算全部Cuboid并保存为物化视图

预计算过程是Kylin从Hive中读取原始数据,按照咱们选定的维度进行计算,并将结果集保存到Hbase中,默认的计算引擎为MapReduce,能够选择Spark做为计算引擎。一次build的结果,咱们称为一个Segment。构建过程当中会涉及多个Cuboid的建立,具体建立过程由kylin.cube.algorithm参数决定,参数值可选 auto,layer 和 inmem, 默认值为 auto,即 Kylin 会经过采集数据动态地选择一个算法 (layer or inmem),若是用户很了解 Kylin 和自身的数据、集群,能够直接设置喜欢的算法。

3)执行查询,读取Cuboid,运行,产生查询结果。

肯定分析角度-即维度(观察数据的角度)
具体聚合运算:count, avg, sum-即度量(被聚合(观察)的统计值,也就是聚合运算的结果)

4个维度组合: abcd abc abc bcd ab cd ac bd a b c d 零维... n个维度---组合--->2^n个cuboid
一个N维的Cube,是由1个N维子立方体、N个(N-1)维子立方体、N*(N-1)/2个(N-2)维子立方体、......、N个1维子立方体和1个0维子立方体构成,总共有2^N个子立方体组成

每种维度组合--->cuboid
全部维度组合的cuboid做为一个总体---->cube(立方体)

核心算法

①分层算 MR--逐层构建算法(layer)

高维---->低维; 数据基于高维,递进过程
缺点:每层都有mr; 每层都要从hdfs读取,大量IO; 简单繁琐

在逐层算法中,按维度数逐层减小来计算,每一个层级的计算(除了第一层,它是从原始数据聚合而来),是基于它上一层级的结果来计算的。

每一轮的计算都是一个MapReduce任务,且串行执行;一个N维的Cube,至少须要N次MapReduce Job。

②快速构建

须要算全部维度,一次mr便可; 多个切片-->多个map数; 作全部keyboid运算; 全部map汇总及cube结果
省去mr资源调度;减小了io; map已经没重复的key,reducer只需对每一个map去重减小了reducer的工做量;

与旧算法相比,快速算法主要有两点不一样:

1) Mapper会利用内存作预聚合,算出全部组合;Mapper输出的每一个Key都是不一样的,这样会减小输出到Hadoop MapReduce的数据量,Combiner也再也不须要;

2)一轮MapReduce便会完成全部层次的计算,减小Hadoop任务的调配。

关于这两个算法麒麟会自动选择;

3. Kylin环境搭建

 /etc/profile

#JAVA_HOME export JAVA_HOME=/opt/module/jdk1.8.0_144 export PATH=$PATH:$JAVA_HOME/bin #HADOOP_HOME export HADOOP_HOME=/opt/module/hadoop-2.7.2 export PATH=$PATH:$HADOOP_HOME/bin export PATH=$PATH:$HADOOP_HOME/sbin #HIVE_HOME export HIVE_HOME=/opt/module/hive export PATH=$PATH:$HIVE_HOME/bin ##HBASE_HOME export HBASE_HOME=/opt/module/hbase-1.3.1 export PATH=$PATH:$HBASE_HOME/bin #KYLIN_HOME export KYLIN_HOME=/opt/module/kylin export PATH=$PATH:$KYLIN_HOME/bin
View Code
1)将apache-kylin-2.5.1-bin-hbase1x.tar.gz上传到Linux 2)解压apache-kylin-2.5.1-bin-hbase1x.tar.gz到/opt/module [kris@hadoop101 sorfware]$ tar -zxvf apache-kylin-2.5.1-bin-hbase1x.tar.gz -C /opt/module/ 注意:须要在/etc/profile文件中配置HADOOP_HOME,HIVE_HOME,HBASE_HOME并source使其生效。 3)启动 [kris@hadoop101 kylin]$ bin/kylin.sh start

启动Kylin以前要保证HDFS,YARN,ZK,HBASE相关进程是正常运行的。

http://hadoop101:7070/kylin 查看Web页面

用户名为:ADMIN,密码为:KYLIN(系统已填)

4. 建立项目

employee实事表才会参与真正运算,dept维表不参与

model模型分如下2种: 
① 当全部维表都直接链接到“ 事实表”上时,整个图解就像星星同样,故将该模型称为星形模型
星状模型是直接关联;

② 当有一个或多个维表没有直接链接到事实表上,而是经过其余维表链接到事实表上时,其图解就像多个雪花链接在一块儿,故称雪花模型。
雪花模型是主从间接关联;

建立分区表:
create
table emp_partition(empno int, ename string, job string, mgr int, sal double, comm double, deptno int) partitioned by(hire_date string) row format delimited fields terminated by '\t'; 动态分区应该手动开启: set hive.exec.dynamic.partition.mode=nonstrict;
动态插入数据
insert into table emp_partition partition(hire_date) select empno, ename, job, mgr, sal, comm, deptno, hiredate from emp;

 

① 建立module项目名称:project_partition

主表--FactTable: default.emp_partition
从表--Add Lookup Table:emp_partition inner join dept
维度--Select dimension columns:EMP_PARTITION-->job,mgr,hire_date ;  DEPT-->dname

度量--Select measure columns: EMP_PARTITION--->sal
② 建立Cube

Cube Designer

 

合并

 

 

 

 与动量cute作呼应,分区必须是日期;选分区表:hire_date

 

 

 

 Kylin查询

在New Query中输入查询语句并Submit

 

数据图表展现及能够导出

5. 可视化

JDBC

新建项目并导入依赖

<dependencies>
        <dependency>
            <groupId>org.apache.kylin</groupId>
            <artifactId>kylin-jdbc</artifactId>
            <version>2.5.1</version>
        </dependency>
    </dependencies>
View Code
public class TestKylin { public static void main(String[] args) throws ClassNotFoundException, SQLException { //kylin的JDBC驱动类 String Kylin_Driver = "org.apache.kylin.jdbc.Driver"; String Kylin_Url = "jdbc:kylin://hadoop101:7070/HelloWorld"; String Kylin_User = "ADMIN"; String Kylin_Password = "KYLIN";    Class.forName(Kylin_Driver); //①添加驱动信息 Connection connection = DriverManager.getConnection(Kylin_Url, Kylin_User, Kylin_Password);//②
      //③预编译SQL PreparedStatement preparedStatement
= connection.prepareStatement("select job, count(*), sum(sal) from EMP inner join DEPT ON EMP.DEPTNO = DEPT.DEPTNO group by job"); ResultSet resultSet = preparedStatement.executeQuery(); //④执行查询 while (resultSet.next()){ //⑤遍历打印 String job = resultSet.getString(1); int count = resultSet.getInt(2); double sum_total = resultSet.getDouble(3); System.out.println(job + "\t" + count + "\t" + sum_total); } } }

 

可视化工具 Zepplin安装与启动

1)将zeppelin-0.8.0-bin-all.tgz上传至Linux 2)解压zeppelin-0.8.0-bin-all.tgz之/opt/module [kris@hadoop101 sorfware]$ tar -zxvf zeppelin-0.8.0-bin-all.tgz -C /opt/module/
3)修更名称 [kris@hadoop101 module]$ mv zeppelin-0.8.0-bin-all/ zeppelin 4)启动 [kris@hadoop101 zeppelin]$ bin/zeppelin-daemon.sh start 可登陆网页查看,web默认端口号为8080 http://hadoop101:8080

 

 

 

 key横坐标;

values纵坐标

%kylin select job, dname, count(*), sum(sal) from EMP inner join DEPT ON EMP.DEPTNO = DEPT.DEPTNO group by job, dname;

6. Cube构建优化

在构建维度数量较多的Cube时,尤为要注意Cube的剪枝优化(即减小Cuboid的生成)。

找出问题Cube

 Expansion Rate即膨胀率;

通常来讲,Cube的膨胀率应该在0%~1000%之间,若是一个Cube的膨胀率超过1000%,那么Cube管理员应当开始挖掘其中的缘由。一般,膨胀率高有如下几个方面的缘由。
  1)Cube中的维度数量较多,且没有进行很好的Cuboid剪枝优化,致使Cuboid数量极多;
  2)Cube中存在较高基数的维度,致使包含这类维度的每个Cuboid占用的空间都很大,这些Cuboid累积形成总体Cube体积变大;
  3)存在比较占用空间的度量,例如Count Distinct,所以须要在Cuboid的每一行中都为其保存一个较大的寄存器,最坏的状况将会致使Cuboid中每一行都有数十KB,从而形成整个Cube的体积变大;

  检查Cube中哪些Cuboid 最终被预计算了,咱们称其为被物化(Materialized)的Cuboid。同时,这种方法还能给出每一个Cuboid所占空间的估计值。因为该工具须要在对数据进行必定阶段的处理以后才能估算Cuboid的大小,所以通常来讲只能在Cube构建完毕以后再使用该工具。

因为同一个Cube的不一样Segment之间仅是输入数据不一样,模型信息和优化策略都是共享的,因此不一样Segment中哪些Cuboid被物化哪些没有被物化都是同样的。所以只要Cube中至少有一个Segment,那么就能使用以下的命令行工具去检查这个Cube中的Cuboid状态:

[kris@hadoop101 kylin]$ bin/kylin.sh org.apache.kylin.engine.mr.common.CubeStatsReader cube_partition Sampling percentage: 100 Mapper overlap ratio: 1.0 Mapper number: 1 Length of dimension DEFAULT.EMP_PARTITION.JOB is 1 Length of dimension DEFAULT.EMP_PARTITION.MGR is 1 Length of dimension DEFAULT.EMP_PARTITION.DEPTNO is 1 Length of dimension DEFAULT.EMP_PARTITION.HIRE_DATE is 1 |---- Cuboid 1111, est row: 14, est MB: 0 |---- Cuboid 0111, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 0011, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 0001, est row: 13, est MB: 0, shrink: 92.86% |---- Cuboid 0010, est row: 3, est MB: 0, shrink: 21.43% |---- Cuboid 0101, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 0100, est row: 7, est MB: 0, shrink: 50% |---- Cuboid 0110, est row: 9, est MB: 0, shrink: 64.29% |---- Cuboid 1011, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 1001, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 1000, est row: 5, est MB: 0, shrink: 35.71% |---- Cuboid 1010, est row: 9, est MB: 0, shrink: 64.29% |---- Cuboid 1101, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 1100, est row: 8, est MB: 0, shrink: 57.14% |---- Cuboid 1110, est row: 10, est MB: 0, shrink: 71.43% 每一个节点表明一个Cuboid,每一个Cuboid都由一连串1或0的数字组成,若是数字为0,则表明这个Cuboid中不存在相应的维度;若是数字为1,则表明这个Cuboid中存在相应的维度。 最高维度1111 3个维度0111 2维 收缩比例: |---- Cuboid 0011, est row: 14, est MB: 0, shrink: 100%(至关于父维度0111是没有收缩的,应该去掉这个节点,它和0111如出一辙) |---- Cuboid 0001, est row: 13, est MB: 0, shrink: 92.86% (相对于它的父维度收缩了,基本上没收缩;减小的) 两个列分组更精细即父维度更精细,子维度相比于父维度应该差异更大,若是差异很小就应该砍掉; 砍的维度越多,Cuboid越少;

 

 构建增量cube

hive中的数据会逐渐增长,cube的构建也须要不断执行,但每次构建cube时,都要把已分析过的旧数据和新数据都从新分析。好比,数据累加了一年,天天作一次数据更新,随之作cube构建,则每次cube面对的数据量都在加大,第366天的分析,要面对第366天 + 以前365天的数据总和。

但愿每次构建cube时,不用全量构建,即不用把全部原始hive表从新构建,而是把新增的hive数据构建一个segment便可

见上建立项目:建立hive分区表--->module中指定分区列(分区列必须为时间列)--->cube增量构建

hive cube -->Segment       -->Segment
      -->Segment ... 全量构建(full
-build) 增量构建() hive cube -->Segment1(2019-2-12)           -->Segment2(2019-3-12)
因为hive中数据变动,kylin会去进行同步,同步一次叫一个segment,每次的segment就是一段一段;
cube关联着hive表,一个cube可能关联屡次segment,关联一次就有一个segment

物化视图的概念

合并

若是任由增量cube,长期生成segment,则势必致使segment过多,聚合量过大,查询性能太低。

因此cube管理员必须制定 segment的合并计划,减小segment数量!

手动合并
在cube中选择"build"的菜单位置,选择"merge"便可触发手动合并;
以后能够选择要合并的时间区间,提交任务便可
自动合并
经过在cube中设置阈值,让cube自动触发segment合并

自动合并(从大到小,如先看28天再看7天;7天合并1次,28天合并一次)作按期的合并

若是有时间跨度达到28天就合并1次;
例如每4天作1次构建,合并一次,作完第7次的构建以后,它和前6次的段就占满了28天,第7次时就占满了28天的间隔,则Segment合并一次;
当没有知足跨度达到28天,再判断有没有连续占满7天的,(它是会先检查大的,大的28天没有,若是7天知足了,就合并);每出现1次新的Segment就会去判断一次;

Retention Threshold中默认值为0,意思是,不丢弃任何segment;如改成20,保留最近20天的Segment,不在这个区间的就舍弃;

构建以前优化:砍掉 Cuboid

优化核心即剪掉不必的cuboid,把它的数量减小点就会更快

 ① 聚合组Aggregation Groups

默认的包含全部的维度,即最全的立方体; 聚合组之间不交叉

根据业务的维度组合,划分出具备强依赖的组合,这些组合称之为聚合组,在聚合组内,维度之间的组合会预计算,聚合组之间并不交叉预计算,从而减小Cuboid的数量.

若是用户仅仅关注维度 AB 组合和维度 CD 组合 那么该 Cube 则能够被分化成两个聚合组,分别是聚合组 AB 和聚合组 CD

 

② 层级维度Hierarchy Dimensions:
层级之间是包含关系
保留比较全的维度,其余的子节点就砍掉;

层级维度是在聚合组内选的;cube的构建是以聚合组为单位的,有几个聚合组就决定了全部Cuboid组合的程度
只有聚合组中的维度才会进行组合;根据层级设置,立方体会去剪掉多余的Cuboid;保留全的维度,剪掉子维度;

用户选择的维度中经常会出现具备层级关系的维度。例如对于国家(country)、省份(province)和城市(city)这三个维度,从上而下来讲国家/省份/城市之间分别是一对多的关系。
也就是说,用户对于这三个维度的查询能够归类为如下三类:
1. group by country 2. group by country, province(等同于group by province) 3. group by country, province, city(等同于 group by city) 若是ABCD 四个维度中ABC这三个被设置为层级维度, abc=ac=bc 则 abcd=acd=bcd,因此剪掉acd,bcd,保留abcd足以, 则最终生成的cube:

 


③ 强制维度Mandatory Dimensions
在全部的维度组合内都有有这个强制维度

若是发如今全部运算中,都会涉及某个维度,则此维度能够被设置为强制维度

假设共有3个维度:A B C

  • 通常状况下的维度组合为以下左图,共有8中可能,则有8次运算;

  • 但若是正真会被用到的运算中都包含A维度,并把A设置为前置维度,则维度组合为以下右图,

共需4次运算;

在后续的查询中是否每次group by都会包含某维度

 

④ 联合维度Joint Dimensions:
A B C为联合维度,3个维度在一块才有意义;

用户有时并不关心维度之间各类细节的组合方式,例如用户的查询语句中仅仅会出现 group by A, B, C,而不会出现 group by A, B 或者 group by C 等等这些细化的维度组合。这一类问题就是联合维度所解决的问题。例如将维度 A、B 和 C 定义为联合维度,Apache Kylin 就仅仅会构建 Cuboid ABC,而 Cuboid AB、BC、A 等等Cuboid 都不会被生成。

A B C为联合维度,则要么都在,要么都不在,以下图,最终的Cuboid 数目从 16 减小到 4。

 

 

⑤ 衍生(推导)维度:

这类维度的意思是可推导的维度,须要该维度对应的一个或者多个列能够和维度表的主键是一对一的,这种维度能够大大减小cuboid个数

Fact表:A(a,b,c)

Lookup表:B(x,y,z)

若是维度c中,每种状况都惟一对应一种 x,y。即 abc==abxy,或者说全部xy的组合均可以替换为c。

因此能够将 x,y 设置为derived维度,能够减小cuboid的个数。

在查询时:select xx from xx group by x,y;会被kylin等价转换为select ... group by c;


A
B C
衍生(推导)维度必须来自从表(维表)
强映射

normal维度来自主表
derived从表的维度默认会被外键(与主键一一对应)推导出来;若是在某种状况下不合理能够改edit改成normal

推导维度不必选聚合组,默认也不会让咱们选,;

相关文章
相关标签/搜索