1. Kylin 概述
1.1 Kylin 定义
Apache Kylin
(麒麟)是一个开源的分布式分析引擎,提供Hadoop/Spark之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由eBay Inc开发并贡献至开源社区。它能在亚秒内查询巨大的Hive表。
官网:https://kylin.apache.org/cn
1.2 Kylin特点
Kylin的主要特点包括支持SQL接口
、支持超大规模数据集
、亚秒级响应
、可伸缩性
、高吞吐率
、BI工具集成
等。
- 标准SQL接口:Kylin是以标准的SQL作为对外服务的接口。
- 支持超大数据集:Kylin对于大数据的支撑能力可能是目前所有技术中最为领先的。早在2015年eBay的生产环境中就能支持百亿记录的秒级查询,之后在移动的应用场景中又有了千亿记录秒级查询的案例。
- 亚秒级响应:Kylin拥有优异的查询相应速度,这点得益于预计算,很多复杂的计算,比如连接、聚合,在离线的预计算过程中就已经完成,这大大降低了查询时刻所需的计算量,提高了响应速度。
- 可伸缩性和高吞吐率:单节点Kylin可实现每秒70个查询,还可以搭建Kylin的集群。
- BI工具集成,Kylin可以与现有的BI工具集成,具体包括如下内容。
- ODBC:与Tableau、Excel、PowerBI等工具集成
- JDBC:与Saiku、BIRT等Java工具集成
- RestAPI:与JavaScript、Web网页集成
- Kylin开发团队还贡献了Zepplin的插件,也可以使用Zepplin来访问Kylin服务。
1.3 预备知识
1.3.1 Data Warehouse(数据仓库)
数据仓库是一个各种数据 (包括历史数据和当前数据)的中心存储系统,是 BI (business intelligence ,商业智能) 的核心部件。
1.3.2 事实表 & 维表
在维度建模中,将度量称为“事实” ,将环境描述为“维度”。维度是用于分析事实所需要的多样环境。例如,在分析交易过程时,可以通过买家、卖家、商品和时间等维度描述交易发生的环境。事实则紧紧围绕着业务过程来设计,通过获取描述业务过程的度量来表达业务过程,包含了引用的维度和与业务过程有关的度量。例如订单作为交易行为的核心载体,直观反映了交易的状况。订单的流转会产生很多业务过程,而下单、支付和成功完结三个业务过程是整个订单的关键节点。获取这三个业务过程的笔数、金额以及转化率是日常数据统计分析的重点,事务事实表设计可以很好地满足这个需求。
1.3.3 维度
即观察数据的角度。比如员工数据,可以从性别角度来分析,也可以更加细化,从入职时间或者地区的维度来观察。维度是一组离散的值,比如说性别中的男和女,或者时间维度上的每一个独立的日期。因此在统计时可以将维度值相同的记录聚合在一起,然后应用聚合函数做累加、平均、最大和最小值等聚合计算。
1.3.4 度量
即被聚合(观察)的统计值,也就是聚合运算的结果。比如说员工数据中不同性别员工的人数,又或者说在同一年入职的员工有多少。
1.3.5 Business Intelligence (商业职能)
商业智能通常被理解为将企业中现有的数据 转化为知识,帮助企业做出明智的业务经营决策的工具。为了将数据转化为知识,需要利用数据仓库 、联机分析处理( OLAP )工具和数据挖掘等技术。
1.3.6 OLAP(online analytical processing)
OLAP是一种软件技术,它使分析人员能够迅速、一致、交互地 从各个方面观察信息 ,以达到深入理解数据的目的。从各方面观察信息,也就是从不同的维度
分析数据,因此 OLAP 也成为 多维分析。
1.3.7 ROLAP & MOLAP
ROLAP : 基于关系型数据库,不需要预计算。
MOLAP:基于多维数据集(一个多维数据集称为一个OLAP Cube),需要预计算。
1.3.8 Cube & Cubeid
有了维度跟度量后就有了根据维度和度量做预计算的Cube理论。给定一个数据模型,我们可以对其上的所有维度进行聚合,对于N个维度来说,组合的所有可能性共有2n种。对于每一种维度的组合,将度量值做聚合计算,然后将结果保存为一个物化视图,称为Cuboid。所有维度组合的Cuboid作为一个整体,称为Cube。
1.3.9 星型模型
当所有维表都直接连接到事实表上时,整个图解就像星星一样,故将该模型称为星型模型。该模型通过大量的冗余来提升查询效率,对OLAP场景较友好。
1.3.10 雪花模型
当有一个或多个维表没有直接连接到事实表上,而是通过其他维度表连接到事实表上时,其图解就像多个雪花连接在一起,故称雪花模型。该模型在MySQL、Oracle中常见。
星型模型 VS 雪花模型
2 Kylin架构
2.1 核心架构
Kylin官方架构图
2.1.1 REST Server
REST Server是一套面向应用程序开发的入口点,旨在实现针对Kylin平台的应用开发工作。此类应用程序可以提供查询、获取结果、触发Cube构建任务、获取元数据以及获取用户权限等等。另外可以通过Restful接口实现SQL查询。
2.1.2 查询引擎(Query Engine)
当Cube准备就绪后,查询引擎就能够获取并解析用户查询。它随后会与系统中的其它组件进行交互,从而向用户返回对应的结果。查询SQL转化为底层任务, 数据存储到HBase。
2.1.3 Routing
负责将解析的SQL生成的执行计划转换成Cube缓存的查询,Cube是通过预计算缓存在hbase中,这部分查询可以在秒级设置毫秒级完成,而且还有一些操作使用过的查询原始数据(存储在Hadoop的HDFS中通过Hive查询)。这部分查询延迟较高(为避免查询原始数据,默认关闭)。
2.1.4 元数据管理工具(Metadata)
Kylin是一款元数据驱动型应用程序。元数据
管理工具是一大关键性组件,用于对保存在Kylin当中的所有元数据进行管理,其中包括最为重要的Cube元数据。其它全部组件的正常运作都需以元数据管理工具为基础。Kylin的元数据存储在Hbase
中。
2.1.5 任务引擎(Cube Build Engine)
这套引擎的设计目的在于处理所有离线任务,其中包括Shell脚本、Java API以及Map Reduce任务等等。任务引擎对Kylin当中的全部任务加以管理与协调,从而确保每一项任务都能得到切实执行并解决其间出现的故障。
2.2 核心算法
2.2.1 工作原理
Kylin的工作原理就是对数据模型做Cube预计算,并利用计算的结果加速查询:
- 指定数据模型,定义维度和度量;
- 预计算Cube,计算所有Cuboid并保存为物化视图,预计算过程是Kylin从Hive中读取原始数据,按照我们选定的维度进行计算,并将结果集保存到Hbase中,默认的计算引擎为MapReduce,可以选择Spark作为计算引擎。一次build的结果,我们称为一个Segment。构建过程中会涉及多个Cuboid的创建,具体创建过程由kylin.Cube.algorithm参数决定,参数值可选 auto,layer 和 inmem, 默认值为 auto,即 Kylin 会通过采集数据动态地选择一个算法 (layer or inmem),如果用户很了解 Kylin 和自身的数据、集群,可以直接设置喜欢的算法。
- 执行查询,读取Cuboid,运行,产生查询结果。
2.2.2 构建方法
主要有逐层构建算法、快速构建算法 两种。
2.2.2.1 逐层构建算法(layer)
一个N维的Cube,是由1个N维子立方体、N个(N-1)维子立方体、N*(N-1)/2个(N-2)维子立方体、……、N个1维子立方体和1个0维子立方体构成,总共有2^N个子立方体组成,在逐层算法中,按维度数逐层减少来计算,每个层级的计算(除了第一层,它是从原始数据聚合而来),是基于它上一层级的结果来计算的。比如,[Group by A, B]的结果,可以基于[Group by A, B, C]的结果,通过去掉C后聚合得来的;这样可以减少重复计算;当 0维度Cuboid计算出来的时候,整个Cube的计算也就完成了。
每一轮的计算都是一个MapReduce任务,且串行执行;一个N维的Cube,至少需要N+1次MapReduce Job。
算法优点:
- 此算法充分利用了MapReduce的能力,处理了中间复杂的排序和洗牌工作,故而算法代码清晰简单,易于维护;
- 受益于Hadoop的日趋成熟,此算法对集群要求低,运行稳定;在内部维护Kylin的过程中,很少遇到在这几步出错的情况;即便是在Hadoop集群比较繁忙的时候,任务也能完成。
算法缺点:
- 当Cube有比较多维度的时候,所需要的MapReduce任务也相应增加;由于Hadoop的任务调度需要耗费额外资源,特别是集群较庞大的时候,反复递交任务造成的额外开销会相当可观;
- 此算法会对Hadoop MapReduce输出较多数据; 虽然已经使用了Combiner来减少从Mapper端到Reducer端的数据传输,所有数据依然需要通过Hadoop MapReduce来排序和组合才能被聚合,无形之中增加了集群的压力;
- 对HDFS的读写操作较多:由于每一层计算的输出会用做下一层计算的输入,这些Key-Value需要写到HDFS上;当所有计算都完成后,Kylin还需要额外的一轮任务将这些文件转成HBase的HFile格式,以导入到HBase中去;总体而言,该算法的效率较低,尤其是当Cube维度数较大的时候。
2.2.2.2 快速构建算法(inmem)
快速构建算法也被称作“逐段”(By Segment) 或“逐块”(By Split) 算法,从1.5.x开始引入该算法,利用Mapper端计算先完成大部分聚合,再将聚合后的结果交给Reducer,从而降低对网络瓶颈的压力。该算法的主要思想是,对Mapper所分配的数据块,将它计算成一个完整的小Cube 段(包含所有Cuboid);每个Mapper将计算完的Cube段输出给Reducer做合并,生成大Cube
,也就是最终结果;如图所示解释了此流程。
快速Cube算法
与旧算法相比,快速算法主要有两点不同。
- Mapper会利用内存做预聚合,算出所有组合;Mapper输出的每个Key都是不同的,这样会减少输出到Hadoop MapReduce的数据量;
- 一轮MapReduce便会完成所有层次的计算,减少Hadoop任务的调配,所以如果机器性能不错推荐用此种方法。
2.2.3 Cube存储原理
假设维度字典表具体信息如下。
字典表信息
加入我们选择了 address、catogory、date为维度进行Cube聚合。我们需要知道Cube底层是如何预聚合后把数据存储到HBase中的。
Cube存储
系统会按照所有的维度选跟不选做01映射,然后每个维度选了后也有对应的维度值做映射。此时 key = Cubeid + 纬度值, value = 对应预聚合结果。
2.3 Kylin 入手
2.3.1 Kylin 安装
Kylin 是依赖于Hadoop、HBase、Zookeeper、Spark的,所以安装时需确保所有的前置依赖是OK的。至于安装细节,找个百度教程即可。
2.3.2 数据准备
在Kylin安装完毕后,需要构建数据源、创建Model、创建Cube等操作,都是一些常规操作,没啥说的。创建模型时整体有点类似PowerBI,需要选择表Join的方式跟字段,选择事实表跟维度的指标跟维度。
2.4 注意事项
因为Routing默认关闭,为了保证OLAP查询的性能稳定,不会出现忽快忽慢的场景,有如下个约束条件。
2.4.1 只能按照构建 Model的连接条件来写 SQL
创建时候如果是A join B,则查询时也只能这样查询。
2.4.2 只能按照构建 Cube时选择的维度字段分组统计
如果我们选择了4个维度,则在进行OLAP查询时候也只能选择这个四个维度进行groupBy。
2.4.3 只能统计构建 Cube时选择的度量值字段
如果在构建Cube时,只添加两个指标,则查询时候也只能查询这俩。别的都不能查询。
3. Cube 构建优化
3.1 使用衍生维度
衍生维度用于在有效维度内将维度表上的非主键维度排除掉,并使用维度表的主键(其
实是事实表上相应的外键)来替代它们。Kylin 会在底层记录维度表主键与维度表其他维度之间的映射关系,以便在查询时能够动态地将维度表的主键“翻译”成这些非主键维度,并进行实时聚合
,(一般不建议开,可能会导致查询耗时变大)。
衍生维度
3.2 使用聚合组(Aggregation Group)
聚合组就是一个强大的剪枝工具,通过指定不同的剪枝策略可以缩小维度组合个数。
3.2.1 强制维度
强制维度
强制维度(Mandatory),如果一个维度被定义为强制维度,分组后的维度组合结果一定要包含该维度,但是强制维度不能自己出现。
3.2.2 层级维度
层级维度
如果指定了维度直接的依赖关系,比如 维度A(年) -> 维度B(月)。维度B不能单独出现,必须B想出现的话必须有A。
3.2.3 联合维度
联合维度
每个联合中包含两个或更多个维度,如果某些列形成一个联合,那么在该分组产生的任何Cuboid中,这些联合维度要么一起出现,要么都不出现。
3.3 Row Key 优化
Kylin 会把所有的维度按照顺序组合成一个完整的Rowkey,并且按照这个Rowkey 升序
排列Cuboid 中所有的行。设计良好的Rowkey 将更有效地完成数据的查询过滤和定位,减少IO 次数,提高查询速度,维度在rowkey 中的次序,对查询性能有显著的影响。
3.3.1 被过滤的维度放在前面
如果A的枚举值是1、2、3、4。B的枚举值a、b、c、d。
过滤
3.3.2 基数打的维度放在基数小的维度前面
如下,想生成AB的结果,则可从ABC、ABD中出结果(ABD结果行数更少),因为kylin系统默认选择cubeid小的,所以基数打的维度尽量前调。
由三个维度生成两个维度
4. 参考
Kylin : https://www.bilibili.com/video/BV1QU4y1F7QH?p=19