Kylin中rowKey编码参考

2019-02-15  本文已影响4人  liuzx32

在Rowkeys设置区域中,每个维度都有几项关键的配置编码:

代表了该维度的值应使用何种方式进行编码,合适的编码能够减少维度对空间的占用,例如,我们可以把所有的日期都用三个字节进行编码,相比于字符串存储,或者是使用长整数形式存储的方法,我们的编码方式能够大大减少每行Cube数据的体积。而Cube中可能存在数以亿计的行数,使用编码节约的空间累加起来将是一个非常巨大的数字。


目前Kylin支持的编码方式有以下几种:

  1. 默认情况下系统可能会对Cuboid的数据进行分片处理,Cuboid的分片策略是随机的,也就是说,我们无法控制Cuboid的哪些行会被分到同一个分片中。这种默认的方法固然能够提高读取的并发程度,但是它仍然有优化的空间。按维度分片(Shard by Dimension)提供了一种更加高效的分片策略,那就是按照某个特定维度进行分片。简单地说,如果Cuboid中某两个行的Shard by Dimension的值相同,那么无论这个Cuboid最终会被划分成多少个分片,这两行数据必然会被分配到同一个分片中。

  2. 这种分片策略对查询有着极大的好处。我们知道,Cuboid的每个分片都会被分配到存储引擎的不同物理机器上。Kylin在读取Cuboid数据的时候会向存储引擎的若干机器发送所读取的RPC请求。在RPC请求接收端,存储引擎会读取本机的分片数据,并在进行一定的预处理后再发送RPC回应。以HBase存储引擎为例,不同的Region代表不同的Cuboid分片,在读取Cuboid数据的时候,HBase会为每个Region开启一个Coprocessor实例来处理查询引擎的请求。查询引擎将查询条件和分组条件作为请求参数的一部分发送到Coprocessor中,Coprocessor就能够在返回结果之前先对当前分片的数据做一定的预聚合(这里的预聚合不是Cube构建的预聚合,而是针对特定查询深度的预聚合)。

  3. 如果按照维度划分分片,假设按照一个基数比较高的维度seller_id进行分片,那么在这种情况下,每个分片将会承担一部分的seller_id,且各个分片不会有相同的seller_id。所有按照seller_id分组(Group byseller_id)的查询都会变得更加高效,因为每个分区预聚合的结果都会更加专注于某一些seller_id之上,使得分片返回的结果数量大大减少,查询引擎端也无需对各个分片的结果做分片间的聚合。按维度分片也能让过滤条件的执行更加高效,因为是按维度分片,所以每个分片的数据都会更加“整洁”,更方便查找和索引。

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

  5. 所以,在调整Rowkeys的顺序时需要遵守以下几个原则:
    在查询中被用作过滤条件的维度有可能放在其他维度的前面。
    将经常出现在查询中的维度放在不经常出现的维度的前面。
    对于基数较高的维度,如果查询会有这个维度上的过滤条件,那么将它往前调整;如果没有,则向后调整。

上一篇 下一篇

猜你喜欢

热点阅读