kylin维度优化指南

先说一下维度表需要遵循的规范:

  1. 维表需要有code和name,比如:city_code city_name
  2. code字段的类型最好使用整数,这样可以加快kylin的构建速度和查询速度
  3. 如果维表是层级维表,比如是国家、省份、城市的层级需要对每个层级都要有对应的code和name,比如:country_code country_name province_code province_name  city_code city_name

本文主要介绍Apache Kylin进行维度优化的常见方法。

为什么需要维度优化

因为如果不进行任何维度优化,直接将所有的维度放在一个聚集组里,Kylin就会计算所有的维度组合(cuboid)。

比如,有12个维度,Kylin就会计算2的12次方即4096个cuboid,实际上查询可能用到的cuboid不到1000个,甚至更少。 如果对维度不进行优化,会造成集群计算和存储资源的浪费,也会影响cube的build时间和查询性能,所以我们需要进行cube的维度优化。

当你在保存cube时遇到下面的异常信息时,意味1个聚集组的维度组合数已经大于 4096 ,你就必须进行维度优化了。

image_1aufkne841pr4155d15bh1cmigf09.png-43.3kB或者发现cube膨胀率过大

如何计算1个聚集组的维度组合数

当有层次维度时,公式如下:
(hierarchy.size() + 1) * hierarchyDimsList.size() * (1 << jointDimsList.size()) * (1 << normalDims.size())

当没有层次维度时,公式如下:
1 << jointDimsList.size()) * (1 << normalDims.size()


hierarchyDimsList.size(): 层次维度的个数。
hierarchy.size(): 每个层次维度包含的维度个数。
jointDimsList.size(): 联合维度的个数。
normalDims.size(): 正常维度的个数,即不是强制维度,层次维度,联合维度的维度数目。

如何进行维度优化

首先请确认你设置的cube维度都是你查询时会使用到的。

目前Kylin可以使用的维度优化手段有以下几种:

  • 聚集组
  • 衍生纬度
  • 强制维度
  • 层次维度
  • 联合维度
  • Extended Column

下文会详细介绍以上维度优化手段的基本概念,以及何时使用这些优化手段。

聚集组

聚集组:用来控制哪些cuboid需要计算。

适用场景:不是只需要计算base cuboid的情况下,都需要聚集组。

注意事项:一个维度可以出现在多个聚集组中,但是build期间只会计算一次。

如果不设置聚集组,默认情况下只会计算 base cuboid。

聚集组不宜太多。

衍生维度

衍生维度:维表中可以由主键推导出值的列可以作为衍⽣维度。

使用场景:以星型模型接入时。例如用户维表可以从userid推导出用户的姓名,年龄,性别。

优化效果:维度表的N个维度组合成的cuboid个数会从2的N次方降为2。

图示: 此处输入图片的描述

强制维度

强制维度:所有cuboid必须包含的维度,不会计算不包含强制维度的cuboid。

适用场景:可以将确定在查询时一定会使用的维度设为强制维度。例如,时间维度。

优化效果:将一个维度设为强制维度,则cuboid个数直接减半。

图示: 强制维度

层次维度

层次维度:具有一定层次关系的维度。

使用场景:像年,月,日;国家,省份,城市这类具有层次关系的维度。

优化效果:将N个维度设置为层次维度,则这N个维度组合成的cuboid个数会从2的N次方减少到N+1。

图示: 此处输入图片的描述

联合维度

联合维度:将几个维度视为一个维度。

适用场景: 1 可以将确定在查询时一定会同时使用的几个维度设为一个联合维度。

2 可以将基数很小的几个维度设为一个联合维度。

3 可以将查询时很少使用的几个维度设为一个联合维度。

优化效果:将N个维度设置为联合维度,则这N个维度组合成的cuboid个数会从2的N次方减少到1。

Extended Column

在OLAP分析场景中,经常存在对某个id进行过滤,但查询结果要展示为name的情况,比如user_id和user_name。这类问题通常有三种解决方式:

a. 将ID和Name都设置为维度,查询语句类似select name, count(*) from table where id = 1 group by id,name。这种方式的问题是会导致维度增多,导致预计算结果膨胀;

b. 将id和name都设置为维度,并且将两者设置为联合。这种方式的好处是保持维度组合数不会增加,但限制了维度的其它优化,比如ID不能再被设置为强制维度或者层次维度;

c. 将ID设置为维度,Name设置为特殊的Measure,类型为Extended Column。这种方式既能保证过滤id且查询name的需求,同时也不影响id维度的进一步优化。

所以此类需求我们推荐使用 Extended Column。

 

 

HBase Rowkey顺序

简单的讲,查询频率越高/基数越大的维度在Rowkey中的顺序需要越靠前。

“shard by”维度列 

选择基数高的维度做分片(sharding),如useid列

可以使MR构建过程按照该列进行重新分布,加快构建速度

 

维度编码

· Dict编码:使用字典将长的值映射成短的ID,适合中低基数的维度,默认推荐编码。但由于字典要被加载到Kylin内存中,在超高基情况下,可能引起内存不足的问题。
· Fixed_Length编码:适用于超高基场景,将选取字段的前N个字节作为编码值,当N小于字段长度,会造成字段截断,当N较大时,造成RowKey过长,查询性能下降。只适用于varchar或nvarchar类型。
· Fixed_Length_Hex编码:适用于字段值为十六进制字符,比如1A2BFF或者FF00FF,每两个字符需要一个字节。只适用于varchar或nvarchar类型。
· Integer编码:将数值类型字段直接用数字表示,不做编码转换。Integer编码需要提供一个额外的参数“Length”来代表需要多少个字节。Length的长度为1到8,支持的整数区间为[ -2^(8*N-1), 2^(8*N-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等类型。
· Boolean编码:用一个byte表示布尔值,适用于字段值为: true, false, TRUE, FALSE, True, False, t, f, T, F, yes, no, YES, NO, Yes, No, y, n, Y, N, 1, 0

 

对于超高基数维度(千万),Too high cardinality is not suitable for dictionary

使用integer(支持int和long), fixed_length

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值