OLAP 玩转KYLIN 步九 官方案列实战之创建Cube之Advanced Setting

紧接上一节数据刷新设置完毕,点击Next,便进入Advanced Setting设置界面。


首先,第一项设置聚合组,如图:
这里写图片描述
合理的聚合组设置,既可以满足查询的需求,也可以优化cube的构建,让我们先理解概念,再谈如何优化。

聚合组既将一个Cube的所有维度根据业务需求划分成若干组(当然也可以是一个组),由于同一个组内的维度更可能同时被同一个查询用到,因此会表现出更加紧密的内在关联。每个分组里的维度组合均是Cube所有维度的一个子集,不同的分组各自拥有一套维度集合,它们可能与其他分组有相同的维度,也可能没有相同的维度。每个分组各自独立地根据自身的
规则贡献出一批需要被物化的Cuboid,所有分组贡献的Cuboid的并集就成为了当前Cube中所有需要物化的Cuboid的集合。不同的分组有可能会贡献出相同的Cuboid,构建引擎会察觉到这点,并且保证每一个Cuboid无论在多少个分组中出现,它都只会被物化一次。
这里写图片描述
对于每个分组内部的维度,用户可以使用如下三种可选的方式定义它们之间的关系,具体如下。
强制维度(Mandatory),如果一个维度被定义为强制维度,那么这个分组产生的所有Cuboid中每一个Cuboid都会包含该维度。每个分组中都可以有0个、1个或多个强制维度。如果根据某个分组的业务逻辑,某个维度一定会在查询的过滤条件或分组条件中,则可以在该分组中把该维度设置为强制维度。
层级维度(Hierarchy),每个层级包含两个或更多个维度。假设一个层级中包含国家,省,市,县/区这4个维度,那么在该分组产生的任何Cuboid中,这4个维度只会以(),(国家),(国家,省),(国家,省,市),(国家,省,市,县/区)这5种形式中的一种出现。每个分组中可以有0个、1个或多个层级,不同的层级之间不应当有共享的维度。如果根据某个分组的业务逻辑,有多个维度存在层级关系,则可以在该分组中把这些维度设置为层级维度。
联合维度(Joint),每个联合中包含两个或更多个维度,如果某些列形成一个联合,那么在该分组产生的任何Cuboid中,这些联合维度要么一起出现,要么都不出现。每个分组中可以有0个或多个联合,但是不同的联合之间不应当有共享的维度(否则它们可以合并成一个联合)。如果根据某个分组的业务逻辑,多个维度在查询中总是同时出现,则可以在该分组中把这些维度设置为联合维度。
聚合组的设计非常灵活,甚至可以用来描述一些极端的设计。假设我们的业务需求非常单一,只需要某些特定的Cuboid,那么可以创建多个聚合组,每个聚合组代表一个Cuboid。具体的方法是在聚合组中先包含某个Cuboid所需的所有维度,然后把这些维度都设置为强制维度。这样当前的聚合组就只能产生我们想要的那一个Cuboid了。
再比如,有的时候我们的Cube中有一些基数非常大的维度,如果不做特殊处理,它就会和其他的维度进行各种组合,从而产生一大堆包含它的Cuboid。包含高基数维度的Cuboid在行数和体积上往往非常庞大,这会导致整个Cube的膨胀率变大。如果根据业务需求知道这个高基数的维度只会与若干个维度(而不是所有维度)同时被查询到,那么就可以通过聚合组对这个高基数维度做一定的“隔离”。我们把这个高基数的维度放入一个单独的聚合组,再把所有可能会与这个高基数维度一起被查询到的其他维度也放进来。这样,这个高基数的维度就被“隔离”在一个聚合组中了,所有不会与它一起被查询到的维度都没有和它一起出现在任何一个分组中,因此也就不会有多余的Cuboid产生。这点也大大减少了包含该高基数维度的Cuboid的数量,可以有效地控制Cube的膨胀率。


接着,第二项设置,Rowkeys,如图:
这里写图片描述
聚合组的侧重点是通过分组聚合,用上面的三种维度减少Cube中Cuboid的数量,尤其是减少那些包含高基数维度的Cuboid的数量,因为这类Cuboid的占用空间往往比其他Cuboid大很多。而通过Cube的Rowkeys方面的设置则会带来Cube查询性能的优化。

在Rowkeys设置区域中,每个维度都有几项关键的配置,下面将逐一讲解。
编码:代表了该维度的值应使用何种方式进行编码,合适的编码能够减少维度对空间的占用,例如,我们可以把所有的日
期都用三个字节进行编码,相比于字符串存储,或者是使用长整数形式存储的方法,我们的编码方式能够大大减少
每行Cube数据的体积。而Cube中可能存在数以亿计的行数,使用编码节约的空间累加起来将是一个非常巨大的数
字。
目前Kylin支持的编码方式有以下几种。

  • ·Date编码:将日期类型的数据使用三个字节进行编码,其支持从0000-01-01到9999-01-01中的每一个日期。
  • ·Time编码:仅支持表示从1970-01-0100:00:00到2038-01-1903:14:07的时间,且Time-stamp类型的维度经过编码和反编码之后,会失去毫秒信息,所以说Time编码仅仅支持到秒。但是Time编码的优势是每个维度仅仅使用4个字节,这相比普通的长整数编码节约了一半。如果能够接受秒级的时间精度,请选择Time编码来代表时间的维度。
  • ·Integer编码:Integer编码需要提供一个额外的参数“Length”来代表需要多少个字节。Length的长度为1~8。如果用来编码int32类型的整数,可以将Length设为4;如果用来编码int64类型的整数,可以将Length设为8。在更多情况下,如果知道一个整数类型维度的可能值都很小,那么就能使用Length为2甚至是1的int编码来存储,这将能够有效避免存储空间的浪费。
  • ·Dict编码:对于使用该种编码的维度,每个Segment在构建的时候都会为这个维度所有可能的值创建一个字典,然后使用字典中每个值的编号来编码。Dict的优势是产生的编码非常紧凑,尤其在维度值的基数较小且长度较大的情况下,特别节约空间。由于产生的字典是在查询时加载入构建引擎和查询引擎的,所以在维度的基数大、长度也大的情况下,容
    易造成构建引擎或查询引擎的内存溢出。
  • ·Fixed_length编码:编码需要提供一个额外的参数“Length”来代表需要多少个字节。该编码可以看作Dict编码的一种补充。对于基数大、长度也大的维度来说,使用Dict可能不能正常工作,于是可以采用一段固定长度的字节来存储代表维度值的字节数组,该数组为字符串形式的维度值的UTF-8字节。如果维度值的长度大于预设的Length,那么超出的部分将会被截断。

维度分片(Shard by Dimension):默认情况下系统可能会对Cuboid的数据进行分片处理,Cuboid的分片策略是随机的,也就是说,我们无法控制Cuboid的哪些行会被分到同一个分片中。这种默认的方法固然能够提高读取的并发程度,但是它仍然有优化的空间。按维度分片(Shard by Dimension)提供了一种更加高效的分片策略,那就是按照某个特定维度进行分片。简单地说,如果Cuboid中某两个行的Shard by Dimension的值相同,那么无论这个Cuboid最终会被划分成多少个分片,这两行数据必然会被分配到同一个分片中。
这种分片策略对查询有着极大的好处。我们知道,Cuboid的每个分片都会被分配到存储引擎的不同物理机器上。Kylin在读取Cuboid数据的时候会向存储引擎的若干机器发送所读取的RPC请求。在RPC请求接收端,存储引擎会读取本机的分片数据,并在进行一定的预处理后再发送RPC回应。以HBase存储引擎为例,不同的Region代表不同的Cuboid分片,在读取Cuboid数据的时候,HBase会为每个Region开启一个Coprocessor实例来处理查询引擎的请求。查询引擎将查询条件和分组条件作为请求参数的一部分发送到Coprocessor中,Coprocessor就能够在返回结果之前先对当前分片的数据做一定的预聚合(这里的预聚合不是Cube构建的预聚合,而是针对特定查询深度的预聚合)。
如果按照维度划分分片,假设按照一个基数比较高的维度seller_id进行分片,那么在这种情况下,每个分片将会承担一部分的seller_id,且各个分片不会有相同的seller_id。所有按照seller_id分组(Group byseller_id)的查询都会变得更加高效,因为每个分区预聚合的结果都会更加专注于某一些seller_id之上,使得分片返回的结果数量大大减少,查询引擎端也无需对各个分片的结果做分片间的聚合。按维度分片也能让过滤条件的执行更加高效,因为是按维度分片,所以每个分片的数据都会更加“整洁”,更方便查找和索引。

调整Rowkeys顺序同样可以优化我们的查询。
在上图中,我们可以上下拖动每一个维度来调节维度在Rowkeys中的顺序。这种顺序对于查询非常重要,因为在目前的实现中,Kylin会把所有的维度按照顺序黏合成一个完整的Rowkeys,并且按照这个Rowkeys升序排列Cuboid中所有的行。
所以,在调整Rowkeys的顺序时需要遵守以下几个原则:

  • 在查询中被用作过滤条件的维度有可能放在其他维度的前面。
  • 将经常出现在查询中的维度放在不经常出现的维度的前面。
  • 对于基数较高的维度,如果查询会有这个维度上的过滤条件,那么将它往前调整;如果没有,则向后调整。

接着,第三项设置,Cube Engine:
这里写图片描述
这里我们可选MapReduce或Spark,这是构建Cube的两种不同的计算框架,实践中我们两者都有过尝试,发现spark的效果并不优于MapReduce,可能是具体场景具体分析,也可能是研究的还不深入,建议一般还是选择MapReduce,足以满足现有的业务需求。


整个的Advanced Setting界面,还有其他几个设置,实践中没有用到,所以默认即可,无需关注。

至此,Advanced Setting界面介绍完毕,只有深入的实践,才能加深对理论的理解,不去实践,永远体会不到这些设置的奥妙之处。
下一节,我们会对构建cube的引擎进行一些参数的配置,根据实际的机器环境,分配合理的计算资源,同样是成功构建cube的关键。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值