一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

上一篇文章( )介绍了Kylin的基本概念和原理。下面介绍Kylin的基本使用。

完整的新建Cube完整流程如下:


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

从0开始新建Cube流程

新建Project

由顶部菜单栏进入 Model 页面,然后点击 【Manage Projects】:


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

点击 【+ Project 】按钮添加一个新的项目:


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

填写Project信息表单:

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

点击 【submit 】按钮提交:

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

同步Hive表

在顶部菜单栏点击 【Model】,然后点击左边的【Data Source】 标签,它会列出所有加载进 Kylin 的表。有两种方式导入表:

  • 通过指定表名导入

点击 【Load Table】 按钮:

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

输入表名并点击 【Sync 】按钮提交请求:


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

  • 浏览Hive数据库选择表名导入

点击 【Load Table From Tree】 按钮:


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

展开数据库节点,点击选择要加载的表,然后点击 【Sync】按钮:


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

说明:同步表定义的界面有一个选择框 【Calculate column cardinality】,勾选后系统会计算 Hive 表每一列的基数,基数是指数据集中出现的不同值的个数,例如“国家”是一个维度,如果有 200 个不同的值,那么此维度的基数就是 200

同步成功后,在左边的 Tables 部分,新加载的表已经被添加进来。点击表将会展开列:


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

在后台,Kylin 将会执行 MapReduce 任务计算新同步表的基数(cardinality),任务完成后,刷新页面并点击表名,基数值将会显示在表信息中。


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

新建 Data Model

创建 cube 前,需定义一个数据模型。数据模型定义了一个星型(star schema)或雪花(snowflake schema)模型。一个模型可以被多个 cube 使用。

Model Info

点击顶部的 【Model】,然后点击 【Models】标签。点击 【+New】 按钮,在下拉框中选择 【New Model】:

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

输入 model 的名字和可选的描述:

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

Model Info主要是填写Model的基本信息,其中Model Name是必填项,模型名称有两点需要注意:

  • 模型名称是全局唯一的,也就是说即便你新建了一个工程,你的模型名称也不能够重复;
  • 模型一旦创建后,模型名称无法被修改。

Data Model

Data Model 主要是构建整体的数据模型,无论你的数据是星型模型或者是雪花模型,需要在这个地方建立数据表之间的关系。

1、选择事实表

输入Model Info之后点击【Next】,在 Fact Table 中,为模型选择事实表:

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

2、建立数据关系

【可选】点击 【Add Lookup Table】 按钮设置事实表与维度表之间的关系:

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

点击 【New Join Condition】按钮,左边选择事实表的外键,右边选择 lookup 表的主键。如果有多于一个 join 列重复执行。

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

点击 “OK”,重复4,5步来添加更多的 lookup 表。完成后,点击 “Next”。

对 “Add Lookup Table” 页面的几点说明:

  • 数据关系不仅仅是事实表与维度表之间(星型模型),维度表和维度表之间(雪花模型)也可以建立联系;
  • 表与表之间的连接添加有三种:“Left Join”、“Inner Join”、“Right Join”;
  • Skip snapshot for this lookup table 选项指的是是否跳过生成 snapshotTable,由于某些 Lookup 表特别大(大于 300M),如果某一个维度的基数比较大 ,可能会导致内存出现 OOM,所以在创建 snapshotTable 的时候会限制原始表的大小不能超过配置的一个上限值(kylin.snapshot.max-mb,默认值300);
  • 跳过构建 snapshot 的 lookup 表将不能搜索,同时不支持设置为衍生维度(Derived)
  • 大部分情况下都是使用 “Left Join”,其他两种 Join 方式不是很常用。

3、完成表关系构建

通过上述的操作即可将事实表以及维度表联系起来,构成一个数据模型:

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

Dimensions

Dimensions 页面允许选择在子 cube 中用作维度的列,然后点击 Columns 列,在下拉框中选择需要的列:


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

在 Dimensions 页面选择可能参与计算的维度,这里被选择的只是在 Cube 构建的时候拥有被选择资格的维度,并不是最后参与Cube构建的维度,建议将维度表中的字段全部选择

Measures

点击 【Next】到达Measures页面,在Measures页面选择可能用于计算的度量。选择作为 measure 的列,其只能从事实表中选择:

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

Settings

1. 点击【Next】到达Settings页面,如果事实表中的数据每日增长,Kylin 支持基于日期的分区,选择 Partition Date Column 中相应的日期列以及日期格式,否则就将其留白。

2. 【可选】选择是否需要time of the day列,默认情况下为 No。如果选择 Yes, 选择 Partition Time Column 中相应的 time 列以及 time 格式


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

3. 【可选】如果在从 hive 抽取数据时候想做一些筛选,可以在 Filter 中输入筛选条件。

需要注意的几点:

  • 时间分区列可以支持日期或更细粒度的时间分区;
  • 时间分区列支持的数据类型有 time/date/datetime/integer等;
  • 过滤条件不需要写 WHERE;
  • 过滤条件不能包含日期维度。

Save

点击 【Save 】然后选择 【Yes 】来保存 data model。创建完成,data model 就会列在左边 Models 列表中。

一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

可以打开Model中的Visualization标签页查询模型的表连接情况:


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

新建 Cube

创建完 data model,可以开始创建 cube。点击顶部 【Model】,然后点击 【Models】标签。点击 【+New】按钮,在下拉框中选择 【New Cube】。

Cube Info

Cube Info 界面主要填写 Cube 的一些基本信息,首先要选择一个Data Model,然后填写 Cube 名称,cube 名字可以使用字母,数字和下划线(空格不允许),Cube 名称全局唯一不能重复。Notification Email List 是运用来通知job执行成功或失败情况的邮箱列表。Notification Events 是触发事件的状态。


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

Cube 信息填写完成后点击【Next】进入下一步。

Dimensions

Dimensions 是维度选择界面,从数据模型的维度中选择一些列作为 Cube 的维度,这个算是 Cube 构建过程中第一个比较重要的环节,这里的设置会影响到生成的 Cuboid 数量,进而影响 Cube 的数据量大小。

点击 【Add Dimension】,在弹窗中显示的事实表和 lookup 表里勾选输入需要的列。Lookup 表的列有2个选项:“Normal” 和 “Derived”(默认)。“Normal” 添加一个普通独立的维度列,“Derived” 添加一个 衍生维度,衍生维度不会计算入 cube,衍生维度对应的外键(FK)参与维度Cuboid,从而降低Cuboid数。在查询时,对衍生维度的查询会首先转换为对外键所在维度的查询,因此会牺牲少量性能(大部分情况下可以接受)。


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

选择所有维度后点击 “Next”。

1、维度选择的建议:

  • 作为 Cube 的维度需要满足下面的条件:可能存在于 where 条件中或者 groupBy 中的维度;
  • 事实表(Fact Table)只选择参与查询的字段,不参与查询的一定不要勾选(即便是外键);
  • 维度表(Lookup Table)中的主键与事实表的外键一一对应,推荐勾选事实表的外键,维度表的主键勾选后选择为衍生(Derived)维度;
  • 对于星型模型而言,维度表的字段往往可以全部为衍生字段;
  • 对于雪花模型而言,如果维度表存在子表,则维度表对于子表的外键推荐作为普通(Normal)维度。

2、特别注意的事项:

  • 表连接的字段并非一定要参与 Cuboid 计算;
  • 表连接的字段如果没有被勾选,且其外键表中没有任何字段作为衍生维度,则该表连接字段是不会参与 Cuboid 的;
  • 一旦被设置为 Normal 类型,则一定会参与 Cuboid 计算;
  • 如果维度表存在层级(例如省市县、日月年等),则推荐分层级的相关字段选择为普通(Normal)维度。

Measures

点击 【+Measure】按钮添加一个新的度量。


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

根据它的表达式共有8种不同类型的度量:SUM、MAX、MIN、COUNT、COUNT_DISTINCT TOP_N, EXTENDED_COLUMN 和 PERCENTILE。请合理选择 COUNT_DISTINCT 和 TOP_N 返回类型,它与 cube 的大小相关。

Refresh Setting

这一步骤是为增量构建 cube 而设计的。

Auto Merge Thresholds: 自动合并小的 segments 到中等甚至更大的 segment。如果不想自动合并,删除默认2个选项。

Volatile Range: 默认为0,会自动合并所有可能的 cube segments,或者用 ‘Auto Merge’ 将不会合并最新的 [Volatile Range] 天的 cube segments。假设 Volatile Range 设置为 7,则最近 7 天内生成的 cube segments 不会被自动合并。

Retention Threshold: 只会保存 cube 过去几天的 segment,旧的 segment 将会自动从头部删除;0表示不启用这个功能。

Partition Start Date: cube 的开始日期。


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

Advanced Setting

聚合组(Aggregation Group)

Cube 中的维度可以划分到多个聚合组中。默认 kylin 会把所有维度放在一个聚合组,当维度较多时,产生的组合数可能是巨大的,会造成 Cube 爆炸;如果你很好的了解你的查询模式,那么你可以创建多个聚合组。在每个聚合组内,使用 “Mandatory Dimensions”, “Hierarchy Dimensions” 和 “Joint Dimensions” 来进一步优化维度组合。

例如查询需求为:污染物排放量在特定的时间范围内,各个区域(省、市、区县三个级别)的排名以及各个流域(一、二、三级流域)的排名。该查询需求就可以氛围两个聚合组:

  • 根据区域维度、时间维度查询污染物排放量;
  • 根据流域维度、时间维度查询污染物排放量。

如果只使用一个聚合组,区域维度和流域维度就很产生很多组合的 Cuboid,然而这些组合对查询毫无用处,此时就可以使用两个聚合组把区域和流域分开,这样便可以大大减少无用的组合。

必要维度(Mandatory Dimension)

必要维度用于总是出现的维度。例如,如果你的查询中总是会带有 “ORDER_DATE” 做为 group by 或 过滤条件, 那么它可以被声明为必要维度。这样一来,所有不含此维度的 cuboid 就可以被跳过计算。

层级维度 (Hierachy Dimension)

层级维度是一组有层级关系的维度,例如:国家->省->市,这里的“国家”是高级别的维度,“省”“市”依次是低级别的维度;用户会按高级别维度进行查询,也会按低级别维度进行查询,但在查询低级别维度时,往往都会带上高级别维度的条件,而不会孤立地审视低级别维度的数据。也就是说,用户对于这三个维度的查询可以归类为以下三类:

  • group by country
  • group by country, province(等同于group by province)
  • group by country, province, city(等同于group by country, city 或者group by city)

联合维度(Joint Dimension)

Joint Dimensions:联合维度,有些维度往往一起出现,或者它们的基数非常接近(有1:1映射关系)。例如 “user_id” 和 “email”。把多个维度定义为组合关系后,所有不符合此关系的 cuboids 会被跳过计算。

就 Joint Dimension (A, B) 来说,在 group by 时 A, B 最好同时出现,这样不损失性能。但如果只出现 A 或者 B,那么就需要在查询时从 group by A,B 的结果做进一步聚合运算,会降低查询的速度。

Rowkeys

Rowkeys是由维度编码值组成。”Dictionary” (字典)是默认的编码方式; 字典只能处理中低基数(少于一千万)的维度;如果维度基数很高(如大于1千万), 选择 “false” 然后为维度输入合适的长度,通常是那列的最大长度值; 如果超过最大值,会被截断。请注意,如果没有字典编码,cube 的大小可能会非常大。

你可以拖拽维度列去调整其在 rowkey 中位置; 位于rowkey前面的列,将可以用来大幅缩小查询的范围。通常建议将 mandantory 维度放在开头, 然后是在过滤 ( where 条件)中起到很大作用的维度;如果多个列都会被用于过滤,将高基数的维度(如 user_id)放在低基数的维度(如 age)的前面。

编码

Kylin 以 Key-Value 的方式将 Cube 存储到 HBase 中,HBase 的 key,也就是 Rowkey,是由各维度的值拼接而成的;为了更高效地存储这些值,Kylin 会对它们进行编码和压缩;每个维度均可以选择合适的编码(Encoding)方式,默认采用的是字典(Dictionary)编码技术;字段支持的基本编码类型如下:

  • dict:适用于大部分字段,默认推荐使用,但在超高基情况下,可能引起内存不足的问题;
  • boolean:适用于字段值为true, false, TRUE, FALSE, True, False, t, f, T, F, yes, no, YES, NO, Yes, No, y, n, Y, N, 1, 0;
  • integer:适用于字段值为整数字符,支持的整数区间为[ -2^(8N-1), 2^(8N-1)];
  • date:适用于字段值为日期字符,支持的格式包括yyyyMMdd、yyyy-MM-dd、yyyy-MM-dd HH:mm:ss、yyyy-MM-dd HH:mm:ss.SSS,其中如果包含时间戳部分会被截断;
  • time:适用于字段值为时间戳字符,支持范围为[ 1970-01-01 00:00:00, 2038/01/19 03:14:07],毫秒部分会被忽略,time编码适用于 time, datetime, timestamp 等类型;
  • fix_length:适用于超高基场景,将选取字段的前 N 个字节作为编码值,当 N 小于字段长度,会造成字段截断,当 N 较大时,造成 RowKey 过长,查询性能下降,只适用于 varchar 或 nvarchar 类型;
  • fixed_length_hex:适用于字段值为十六进制字符,比如 1A2BFF 或者 FF00FF,每两个字符需要一个字节,只适用于 varchar 或 nvarchar 类型。

顺序

各维度在 Rowkeys 中的顺序,对于查询的性能会产生较明显的影响;在这里用户可以根据查询的模式和习惯,通过拖曳的方式调整各个维度在Rowkeys上的顺序。推荐的顺序为:Mandatory 维度、where 过滤条件中出现频率较多的维度、高基数维度、低基数维度。这样做的好处是,充分利用过滤条件来缩小在 HBase 中扫描的范围,从而提高查询的效率。

分片

指定 ShardBy 的列,明细数据将按照该列的值分片;没有指定 ShardBy 的列,则默认将根据所有列中的数据进行分片;选择适当的 ShardBy 列,可以使明细数据较为均匀的分散在多个数据片上,提高并行性,进而获得更理想的查询效率;建议选择基数较大的列作为 ShardBy 列,以避免数据分散不均匀

其他设置

  • Mandatory Cuboids: 维度组合白名单。确保你想要构建的 cuboid 能被构建。
  • Cube Engine: cube 构建引擎。有两种:MapReduce 和 Spark。如果你的 cube 只有简单度量(SUM, MIN, MAX),建议使用 Spark。如果 cube 中有复杂类型度量(COUNT DISTINCT, TOP_N),建议使用 MapReduce。
  • Advanced Dictionaries: “Global Dictionary” 是用于精确计算 COUNT DISTINCT 的字典, 它会将一个非 integer的值转成 integer,以便于 bitmap 进行去重。如果你要计算 COUNT DISTINCT 的列本身已经是 integer 类型,那么不需要定义 Global Dictionary。 Global Dictionary 会被所有 segment 共享,因此支持在跨 segments 之间做上卷去重操作。请注意,Global Dictionary 随着数据的加载,可能会不断变大。
  • “Segment Dictionary” 是另一个用于精确计算 COUNT DISTINCT 的字典,与 Global Dictionary 不同的是,它是基于一个 segment 的值构建的,因此不支持跨 segments 的汇总计算。如果你的 cube 不是分区的或者能保证你的所有 SQL 按照 partition_column 进行 group by, 那么你应该使用 “Segment Dictionary” 而不是 “Global Dictionary”,这样可以避免单个字典过大的问题。
  • 请注意:”Global Dictionary” 和 “Segment Dictionary” 都是单向编码的字典,仅用于 COUNT DISTINCT 计算(将非 integer 类型转成 integer 用于 bitmap计算),他们不支持解码,因此不能为普通维度编码。
  • Advanced Snapshot Table: 为全局 lookup 表而设计,提供不同的存储类型。
  • Advanced ColumnFamily: 如果有超过一个的COUNT DISTINCT 或 TopN 度量, 你可以将它们放在更多列簇中,以优化与HBase 的I/O。

Configuration Overwrites

Kylin 使用了很多配置参数以提高灵活性,用户可以根据具体的环境、场景等配置不同的参数进行调优;Kylin 全局的参数值可在 kylin.properties 文件中进行配置;如果 Cube 需要覆盖全局设置的话,则需要在此页面中指定,这些配置项将覆盖项目级别和配置文件中的默认值。


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

Overview

你可以概览你的 cube 并返回之前的步骤进行修改。点击 Save 按钮完成 cube 创建。


一款高性能的OLAP分析工具-Apache Kylin 研究 (二)

经过以上步骤,就从0开始完整的创建了一个Cube,下一篇我们将说明如果构建Cube。


分享到:


相關文章: