上一篇文章(一款高性能的OLAP分析工具-Apache Kylin 研究 (一))介绍了Kylin的基本概念和原理。下面介绍Kylin的基本使用。
完整的新建Cube完整流程如下:
![1ca7b38905e11b57c19af449bf583360.png](https://i-blog.csdnimg.cn/blog_migrate/885e2a11e1c7918b4ec88d71626a8277.jpeg)
从0开始新建Cube流程
新建Project
由顶部菜单栏进入 Model 页面,然后点击 【Manage Projects】:
![112f0b2f9fdb6112cda6db969f61e274.png](https://i-blog.csdnimg.cn/blog_migrate/933d4f89f554d6d762f5042f43e1557e.jpeg)
点击 【+ Project 】按钮添加一个新的项目:
![29b786309eee8f879a5b2d72e8775209.png](https://i-blog.csdnimg.cn/blog_migrate/c2e683251c3463b6122d24b008efed88.jpeg)
填写Project信息表单:
![8bb0d200d01aca44778a8ba10aa9d818.png](https://i-blog.csdnimg.cn/blog_migrate/c4dbfbaa83bd387df3883d66b1875725.jpeg)
点击 【submit 】按钮提交:
![60b058d60eb2e2bccfc135babb1f25f9.png](https://i-blog.csdnimg.cn/blog_migrate/154125c06957ab4ed6a6d598e31b5b3a.jpeg)
同步Hive表
在顶部菜单栏点击 【Model】,然后点击左边的【Data Source】 标签,它会列出所有加载进 Kylin 的表。有两种方式导入表:
- 通过指定表名导入
点击 【Load Table】 按钮:
![89fad9e42783f46c9f3f8643fed071ba.png](https://i-blog.csdnimg.cn/blog_migrate/017dff32a1ef20848e1984083cdeaf90.jpeg)
输入表名并点击 【Sync 】按钮提交请求:
![e68af0ef0571c602900d2bf3062f3b3b.png](https://i-blog.csdnimg.cn/blog_migrate/d98d7a1fd56d739510288bf30a4c976c.jpeg)
- 浏览Hive数据库选择表名导入
点击 【Load Table From Tree】 按钮:
![c0a4a180f814dc035cf4002bc1fed884.png](https://i-blog.csdnimg.cn/blog_migrate/c7597ead3e55ddf180fed74289e72f8b.jpeg)
展开数据库节点,点击选择要加载的表,然后点击 【Sync】按钮:
![fb3545611be65b8f77264e4857c8288b.png](https://i-blog.csdnimg.cn/blog_migrate/35929b6b0d676dd9bb20d8361e017451.jpeg)
说明:同步表定义的界面有一个选择框 【Calculate column cardinality】,勾选后系统会计算 Hive 表每一列的基数,基数是指数据集中出现的不同值的个数,例如“国家”是一个维度,如果有 200 个不同的值,那么此维度的基数就是 200
同步成功后,在左边的 Tables 部分,新加载的表已经被添加进来。点击表将会展开列:
![f65989316a6363e90aa822f9737bb983.png](https://i-blog.csdnimg.cn/blog_migrate/6d1b5f3a685f1082cdf5885bf0e0d3a7.jpeg)
在后台,Kylin 将会执行 MapReduce 任务计算新同步表的基数(cardinality),任务完成后,刷新页面并点击表名,基数值将会显示在表信息中。
![94a426899ad7e3271d5ecf4e3e924a5f.png](https://i-blog.csdnimg.cn/blog_migrate/dc27a949e0098d08074d1503a5ef34eb.jpeg)
新建 Data Model
创建 cube 前,需定义一个数据模型。数据模型定义了一个星型(star schema)或雪花(snowflake schema)模型。一个模型可以被多个 cube 使用。
Model Info
点击顶部的 【Model】,然后点击 【Models】标签。点击 【+New】 按钮,在下拉框中选择 【New Model】:
![1695bccd143a4108f14214c9c877400b.png](https://i-blog.csdnimg.cn/blog_migrate/24f3e9fa8e739eebe2c0de45f39de71f.jpeg)
输入 model 的名字和可选的描述:
![ddfdba649960473b6fa9b0fe26791960.png](https://i-blog.csdnimg.cn/blog_migrate/aff5a4d01d5f007415302426c9652895.jpeg)
Model Info主要是填写Model的基本信息,其中Model Name是必填项,模型名称有两点需要注意:
- 模型名称是全局唯一的,也就是说即便你新建了一个工程,你的模型名称也不能够重复;
- 模型一旦创建后,模型名称无法被修改。
Data Model
Data Model 主要是构建整体的数据模型,无论你的数据是星型模型或者是雪花模型,需要在这个地方建立数据表之间的关系。
1、选择事实表
输入Model Info之后点击【Next】,在 Fact Table 中,为模型选择事实表:
![3ab61db867f33221eab6246e0fcdf5b8.png](https://i-blog.csdnimg.cn/blog_migrate/fb189aa0ffcec8d7030694e258e73cf4.jpeg)
2、建立数据关系
【可选】点击 【Add Lookup Table】 按钮设置事实表与维度表之间的关系:
![fa041538080c7ef445ac3b50dc2a35f7.png](https://i-blog.csdnimg.cn/blog_migrate/80a14155ba62fde1dcd8034689e18568.jpeg)
点击 【New Join Condition】按钮,左边选择事实表的外键,右边选择 lookup 表的主键。如果有多于一个 join 列重复执行。
![abef7803b51fdfad07ccd20c2f60ed4d.png](https://i-blog.csdnimg.cn/blog_migrate/092df786c97f5006d044466f9a53a23f.jpeg)
点击 “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、完成表关系构建
通过上述的操作即可将事实表以及维度表联系起来,构成一个数据模型:
![da597a84d3e27b0c6d3351bb798f4a38.png](https://i-blog.csdnimg.cn/blog_migrate/96f62c38e6c208583100e7c6243caa64.jpeg)
Dimensions
Dimensions 页面允许选择在子 cube 中用作维度的列,然后点击 Columns 列,在下拉框中选择需要的列:
![b819493ade64e80b3ed6696a348ed686.png](https://i-blog.csdnimg.cn/blog_migrate/9c512dc01d22da489e6e70928eb627f2.jpeg)
在 Dimensions 页面选择可能参与计算的维度,这里被选择的只是在 Cube 构建的时候拥有被选择资格的维度,并不是最后参与Cube构建的维度,建议将维度表中的字段全部选择。
Measures
点击 【Next】到达Measures页面,在Measures页面选择可能用于计算的度量。选择作为 measure 的列,其只能从事实表中选择:
![0298887e3f206f878c73ce891d13550e.png](https://i-blog.csdnimg.cn/blog_migrate/170a72b78148343711f5acd62168ca95.jpeg)
Settings
1. 点击【Next】到达Settings页面,如果事实表中的数据每日增长,Kylin 支持基于日期的分区,选择 Partition Date Column 中相应的日期列以及日期格式,否则就将其留白。
2. 【可选】选择是否需要time of the day列,默认情况下为 No。如果选择 Yes, 选择 Partition Time Column 中相应的 time 列以及 time 格式
![debdc45f038c25f4e23af1e958371dcb.png](https://i-blog.csdnimg.cn/blog_migrate/2ba795dc98cb6872a4c2a55721896ac9.jpeg)
3. 【可选】如果在从 hive 抽取数据时候想做一些筛选,可以在 Filter 中输入筛选条件。
需要注意的几点:
- 时间分区列可以支持日期或更细粒度的时间分区;
- 时间分区列支持的数据类型有 time/date/datetime/integer等;
- 过滤条件不需要写 WHERE;
- 过滤条件不能包含日期维度。
Save
点击 【Save 】然后选择 【Yes 】来保存 data model。创建完成,data model 就会列在左边 Models 列表中。
![94698d1a9de7fc1564ec3db33b01b3d4.png](https://i-blog.csdnimg.cn/blog_migrate/91ffac6cf2a01e7c2450f5f9c698f531.jpeg)
可以打开Model中的Visualization标签页查询模型的表连接情况:
![ff0ad43085a82991411f15f7af74c8d0.png](https://i-blog.csdnimg.cn/blog_migrate/63e1a4f726cdb18714a286ceb3e2e48c.jpeg)
新建 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 是触发事件的状态。
![9d665a432ac8685de0f3a983ec36b190.png](https://i-blog.csdnimg.cn/blog_migrate/d06f3b74c1af57d724c520482b32ad54.jpeg)
Cube 信息填写完成后点击【Next】进入下一步。
Dimensions
Dimensions 是维度选择界面,从数据模型的维度中选择一些列作为 Cube 的维度,这个算是 Cube 构建过程中第一个比较重要的环节,这里的设置会影响到生成的 Cuboid 数量,进而影响 Cube 的数据量大小。
点击 【Add Dimension】,在弹窗中显示的事实表和 lookup 表里勾选输入需要的列。Lookup 表的列有2个选项:“Normal” 和 “Derived”(默认)。“Normal” 添加一个普通独立的维度列,“Derived” 添加一个 衍生维度,衍生维度不会计算入 cube,衍生维度对应的外键(FK)参与维度Cuboid,从而降低Cuboid数。在查询时,对衍生维度的查询会首先转换为对外键所在维度的查询,因此会牺牲少量性能(大部分情况下可以接受)。
![bab59034e1f061e8ed2ba648361451a3.png](https://i-blog.csdnimg.cn/blog_migrate/4f6870675c0a710d2ec1526a726e8b28.jpeg)
选择所有维度后点击 “Next”。
1、维度选择的建议:
- 作为 Cube 的维度需要满足下面的条件:可能存在于 where 条件中或者 groupBy 中的维度;
- 事实表(Fact Table)只选择参与查询的字段,不参与查询的一定不要勾选(即便是外键);
- 维度表(Lookup Table)中的主键与事实表的外键一一对应,推荐勾选事实表的外键,维度表的主键勾选后选择为衍生(Derived)维度;
- 对于星型模型而言,维度表的字段往往可以全部为衍生字段;
- 对于雪花模型而言,如果维度表存在子表,则维度表对于子表的外键推荐作为普通(Normal)维度。
2、特别注意的事项:
- 表连接的字段并非一定要参与 Cuboid 计算;
- 表连接的字段如果没有被勾选,且其外键表中没有任何字段作为衍生维度,则该表连接字段是不会参与 Cuboid 的;
- 一旦被设置为 Normal 类型,则一定会参与 Cuboid 计算;
- 如果维度表存在层级(例如省市县、日月年等),则推荐分层级的相关字段选择为普通(Normal)维度。
Measures
点击 【+Measure】按钮添加一个新的度量。
![c35020ad3d66f397ad9ab90468c0a3f0.png](https://i-blog.csdnimg.cn/blog_migrate/0ebb0d780b7c83ed17e894f99ca1e3b1.jpeg)
根据它的表达式共有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 的开始日期。
![e4dbea5957a96d6669e8d79a835af33d.png](https://i-blog.csdnimg.cn/blog_migrate/2f5df0aa62650e302b9e751d74e7b60c.jpeg)
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 需要覆盖全局设置的话,则需要在此页面中指定,这些配置项将覆盖项目级别和配置文件中的默认值。
![3cfa4105a52942bdcf3bac6385c5d0a8.png](https://i-blog.csdnimg.cn/blog_migrate/4566b19b85082b3d605014e837d9d1c2.jpeg)
Overview
你可以概览你的 cube 并返回之前的步骤进行修改。点击 Save 按钮完成 cube 创建。
![6c8458b718978d4acc0e43124267e6ed.png](https://i-blog.csdnimg.cn/blog_migrate/c308431b4f627cb5e914ac7ec0b1008a.jpeg)
经过以上步骤,就从0开始完整的创建了一个Cube,下一篇我们将说明如果构建Cube。