Apache Kylin 是一个开源的分布式分析引擎,提供 Hadoop/Spark 之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由 eBay Inc 开发并贡献至开源社区。它能在亚秒内查询巨大的 Hive 表。
1)REST Server
REST Server 是一套面向应用程序开发的入口点,旨在实现针对 Kylin 平台的应用开发工作。 此类应用程序可以提供查询、获取结果、触发 cube 构建任务、获取元数据以及获取用户权限等等。另外可以通过 Restful 接口实现 SQL 查询。
2)查询引擎(Query Engine)
当 cube 准备就绪后,查询引擎就能够获取并解析用户查询。它随后会与系统中的其它组件进行交互,从而向用户返回对应的结果。
3)路由器(Routing)
在最初设计时曾考虑过将 Kylin 不能执行的查询引导去 Hive 中继续执行,但在实践后发现 Hive 与 Kylin 的速度差异过大,导致用户无法对查询的速度有一致的期望,很可能大多数查询几秒内就返回结果了,而有些查询则要等几分钟到几十分钟,因此体验非常糟糕。
最后这个路由功能在发行版中默认关闭。
4)元数据管理工具(Metadata)
Kylin 是一款元数据驱动型应用程序。元数据管理工具是一大关键性组件,用于对保存在 Kylin 当中的所有元数据进行管理,其中包括最为重要的 cube 元数据。其它全部组件的正常运作都需以元数据管理工具为基础。 Kylin 的元数据存储在 hbase 中。
5)任务引擎(Cube Build Engine)
这套引擎的设计目的在于处理所有离线任务,其中包括 shell 脚本、Java API 以及 Map Reduce 任务等等。任务引擎对 Kylin 当中的全部任务加以管理与协调,从而确保每一项任务都能得到切实执行并解决其间出现的故障。
数据仓库,OLAP
与OLTP
,维度和度量,事实表和维度表。星型模型和雪花模型。
DW
这是商业智能(BI
)的核心部分,主要是将不同数据源的数据整合到一起,通过多维分析为企业提供决策支持、报表生成等。存入数据仓库的资料必定包含时间属性。
数据仓库和数据库主要区别:用途不同。
数据库 | 数据仓库 |
---|---|
面向事务 存储在线的业务数据,对上层业务改变作出实时反映,遵循三范式设计。 |
面向分析 历史数据,主要为企业决策提供支持,数据可能存在大量冗余,但是利于多个维度查询,为决策者提供更多观察视角。 |
一般来说,在传统BI
领域里,数据仓库的数据同样是存储在MySQL
这样的数据库中。大数据领域最常用的数据仓库就是Hive
,我们要学习的Kylin
也是以Hive
作为默认的数据源的。
OLAP
和OLTP
OLAP
(Online Analytical Process
),联机分析处理,大量历史数据为基础,配合时间点的差异,以多维度的方式分析数据, 一般带有主观的查询需求,多应用在数据仓库。
OLTP
(Online Transaction Process
),联机事务处理,侧重于数据库的增删查改等常用业务操作。
在数仓的dwd层,要进行维度建模;会产生一些事实表和维度表。事实表分为两部分,一部分数维度id以及退化的维度字段,另一部分是度量值。维度表:一般是对事实的描述信息。每一张维表对应现实世界中的一个对象或者概念。
例如:用户、商品、日期、地区等。
事实表中的每行数据代表一个业务事件(下单、支付、退款、评价等)。“ 事实 ” 这个术语表示的是业务事件的度量值(可统计次数、个数、金额等),例如,2022 年 2月 14日,张三在京东花了25元买了一瓶六味地黄丸。维度:时间、用户、商品、商家。事实:250元、一瓶。
每一个事实表的行包括:具有可加性的数值型的度量值、与维表相连接的外键,通常具有两个和两个以上的外键。
维度和度量是数据分析领域中两个常用的概念。
维度( Dimension )简单来说就是你观察数据的角度,也就是数据记录的一个属性例如时间、地点等。
度量( Measure )就是基于数据所计算出来的考量值,通常就是一个数据比如总销售额,不同的用户数量。我们就是从不同的维度来审查度量值,以便我们分析找出其中的变化规律。
对应我们的 SQL 查询, group by 的属性通常就是我们考量的维度,所计算出来的比如 sum (字段)就是我们需要的度量。
维度为:
度量值有:
那么假设我们以商品的销售时间、门店市场market和品类为分析维度进行统计商品的总销售额,则SQL如下:
select saledate,market,category,SUM(sales) as sumsales from kylin_sale group by saledate,market,category;
有了维度跟度量,一个数据表或者数据模型上的所有字段就可以分类了,它们要么是维度,要么是度量(可以被聚合)。于是就有了根据维度和度量做预计算的 Cube 理论。给定一个数据模型,我们可以对其上的所有维度进行聚合,对于 N 个维度来说,组合的所有可能性共有 2 n {2^n} 2n 种。**对于每一种维度的组合,将度量值做聚合计算,然后将结果保存为一个物化视图,称为 Cuboid。**所有维度组合的 Cuboid 作为一个整体,称为 Cube。
下面举一个简单的例子说明,假设有一个电商的销售数据集,其中维度包括时间[time]、商品[item]、地区[location]和供应商[supplier],度量为销售额。那么所有维度的组合就有 2 4 = 16 {2^4=16} 24=16 种,如下图所示:
一维度(1D)的组合有:[time]、[item]、[location]和[supplier]4 种;----> C 4 1 = 4 {C_4^1=4} C41=4
二维度(2D)的组合有:[time, item]、[time, location]、[time,supplier]、[item, location]、[item, supplier]、[location, supplier] 6种;—> C 4 2 = 6 {C_4^2=6} C42=6
三维度(3D)的组合也有 4 种;—> C 4 3 = 4 {C_4^3=4} C43=4
四维度(4D)的组合1种—> C 4 4 = 1 {C_4^4=1} C44=1
最后还有零维度(0D)一种,总共 16 种。
注意:每一种维度组合就是一个 Cuboid,16 个 Cuboid 整体就是一个 Cube。
我们在确定好了维度和度量之后,我们根据定义好的维度和度量,就可以构建 cube(立方体)。也就是所谓的预计算,对原始数据建立的多维度索引。给定一个数据模型,我们可以对其上的所有维度进行组合。对于N个维度来说,组合的所有可能性共有 2 n {2^n} 2n 种。对于每一种维度的组合,将度量做聚合运算,然后将运算的结果保存为一个物化视图,称为Cuboid 。所有维度组合的 Cuboid 作为一个整体,被称为Cube。
一个cube对应一个星型模型或雪花模型,星型模型就是一张事实表,以及零个或多个维度表;事实表与维度表通过主键外键相关联。
雪花模型:
将星形模型中的某些维表抽取成更细粒度的维表,然后让维表之间也进行关联,这种形状酷似雪花的的模型称为雪花模型。
星型模型因为数据的冗余所以很多统计查询不需要做外部的关联,因此一般情况下效率比雪花型模型要高。星型结构不用考虑很多正规化的因素,设计与实现都比较简单。
雪花型模型由于去除了冗余,有些统计就需要通过表的联接才能产生,所以效率不一定有星型模型高。正规化也是一种比较复杂的过程,相应的数据库结构设计、数据的 ETL 、以及后期的维护都要复杂一些。因此在冗余可以接受的前提下,实际运用中星型模型使用更多,也更有效率。
一个cube对应一个星型模型或雪花模型,一个星型模型对应一张事实表和多张维度表。一个事实表对应一个业务线,事实表与维表之间进行关联。因此在使用kylin时步骤如下:
创建project,对应我们的hive库
选择所需数据表,并点击 Sync 按钮—>数据同步
根据一条业务线进行表单选择,例如订单事实明细表,选择业务线相关的维度—>省份地区、商品维、用户维选择这3个维度构建cube
构建 cube
1)点击 new, 并点击 new cube
2)填写 cube 信息,选择 cube 所依赖的 model,并点击 next
3)选择所需的维度,如下图所示
4)选择所需度量值,如下图所示
5)cube 自动合并设置,cube 需按照日期分区字段每天进行构建,每次构建的结果会保存在Hbase 中的一张表内,为提高查询效率,需将每日的 cube 进行合并,此处可设置合并周期。
5)Kylin 高级配置(优化相关,暂时跳过)
6)Kylin 相关属性配置覆盖
7)Cube 信息总览,点击 Save,Cube 创建完成
8)构建 Cube(计算),点击对应 Cube 的 action 按钮,选择 build
9)选择要构建的时间区间,点击 Submit
10)点击 Monitor 查看构建进度
维度字典表
Hbase K-V
[外链图片转存失败,源站可能
Cuboid id—>111表示地址、品类、订单日期三个维度都有,维度值000—>表示维度字段编码值对应的维度字段,
如0–>北京,0–>电子类,0–>表示2019年-01-09
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次 MapReduce Job。
Cube 逐层构建算法
算法优点:
1)此算法充分利用了 MapReduce 的优点,处理了中间复杂的排序和 shuffle 工作,故而算法代码清晰简单,易于维护;
2)受益于 Hadoop 的日趋成熟,此算法非常稳定,即便是集群资源紧张时,也能保证最终能够完成。
算法缺点:
1)当 Cube 有比较多维度的时候,所需要的 MapReduce 任务也相应增加;由于 Hadoop的任务调度需要耗费额外资源,特别是集群较庞大的时候,反复递交任务造成的额外开销会相当可观;
2)由于 Mapper 逻辑中并未进行聚合操作,所以每轮 MR 的 shuffle 工作量都很大,导致效率低下。
3)对 HDFS 的读写操作较多:由于每一层计算的输出会用做下一层计算的输入,这些Key-Value 需要写到 HDFS 上;当所有计算都完成后,Kylin 还需要额外的一轮任务将这些文件转成 HBase 的 HFile 格式,以导入到 HBase 中去;
总体而言,该算法的效率较低,尤其是当 Cube 维度数较大的时候。
2)快速构建算法(inmem)
也被称作“逐段”(By Segment) 或“逐块”(By Split) 算法,从 1.5.x 开始引入该算法,该算法的主要思想是,每个 Mapper 将其所分配到的数据块,计算成一个完整的小 Cube 段(包含所有 Cuboid)。每个 Mapper 将计算完的 Cube 段输出给 Reducer 做合并,生成大 Cube,也就是最终结果。如图所示解释了此流程。
Cube 快速构建算法
与旧算法相比,快速算法主要有两点不同:
1)Mapper 会利用内存做预聚合,算出所有组合;Mapper 输出的每个 Key 都是不同的,这样会减少输出到 Hadoop MapReduce 的数据量,Combiner 也不再需要;
)。每个 Mapper 将计算完的 Cube 段输出给 Reducer 做合并,生成大 Cube,也就是最终结果。如图所示解释了此流程。
Cube 快速构建算法
与旧算法相比,快速算法主要有两点不同:
1)Mapper 会利用内存做预聚合,算出所有组合;Mapper 输出的每个 Key 都是不同的,这样会减少输出到 Hadoop MapReduce 的数据量,Combiner 也不再需要;
2)一轮 MapReduce 便会完成所有层次的计算,减少 Hadoop 任务的调配。
离线电商数仓3.0项目的即席查询复盘笔记