![](https://csdnimg.cn/release/download_crawler_static/86318142/bg8.jpg)
第 5 层的 cuboid 有 7 种,分别为{brand、product、year、quart、location}、
{brand、product、year、quart、momth}、{brand、location、year、quart、
month}、{product、location、year、quart、month}、{brand、year、quart、
month、day}、{product、year、quart、month、day}、{location、year、quart、
month、day}
第 6 层的 cuboid 有 5 种,分别为{brand、product、year、quart、month、
location}、{brand、product、year、quart、momth、day}、{brand、location、
year、quart、month、day}、{product、location、year、quart、month、day}
第 7 层的 cuboid 有 1 中,为{brand、product、year、quart、month、day、
location}
所以一共 40 个 cuboid(kylin 计算的是 39 个,应该没有把第 0 层的计算在内)。
2.6、增量 Cube
由于 kylin 的核心在于预计算缓存数据,那么对于实时的数据查询的支持就不如
mondrian 好了,但是一般情况下我们数据分析并没有完全实时的要求,数据延迟几个小时
甚至一天是可以接受的,kylin 提供了增量 cube 的接口,kylin 的实现是一个 cube(这里是指
逻辑上的 cube)中可以包含多个 segment,每一个 segment 对应着一个物理 cube,在实际
存储上对应着一个 hbase 的一个表,用户定义根据某一个字段进行增量(目前仅支持时间,
并且这个字段必须是 hive 的一个分区字段),在使用的时候首先需要定义好 cube 的定义,
可以指定一个时间的 partition 字段作为增量 cube 的依赖字段,其实这个选择是作为原始数
据选择的条件,例如选择起始时间 A 到 B 的数据那么创建的 cube 则会只包含这个时间段的
数据聚合值,创建完一个 cube 之后可以再次基于以前的 cube 进行 build,每次 build 会生成
一个新的 segment,只不过原始数据不一样了(根据每次 build 指定的时间区间),每次查
询的时候会查询所有的 segment 聚合之后的值进行返回,有点类似于 tablet 的存储方式,但
是当 segment 存在过多的时候查询效率就会下降,因此需要在存在多个 segment 的时候将它
们进行合并,合并的时候其实是指定了一个时间区间,内部会选择这个时间区间内的所有
segment 进行合并,合并完成之后使用新的 segment 替换被合并的多个 segment,合并的执
行是非常迅速的,数据不需要再从 HDFS 中获取,直接将两个 hbase 表中相同 key 的数据进
行聚合就可以了。但是有一点需要注意的是当合并完成之后,被合并的几个 segment 所对应
的 hbase 表并没有被删除。实际的使用过程中对于增量的 cube 可以写个定时任务每天凌晨
进行 build,当达到一个数目之后进行 merge(其实每次 build 完成之后都进行 merge 也应该
是可以的)。
2.7、Cube 的词典树
Kylin 的 cube 数据是作为 key-value 结构存储在 hbase 中的,key 是每一个维度成员的组
合值,不同的 cuboid 下面的 key 的结构是不一样的,例如 cuboid={brand,product,year}下
面的一个 key 可能是 brand='Nike',product='shoe',year=2015,那么这个 key 就可以写成
Nike:shoe:2015,但是如果使用这种方式的话会出现很多重复,所以一般情况下我们会把一
个维度下的所有成员取出来,然后保存在一个数组里面,使用数组的下标组合成为一个 key,
这样可以大大节省 key 的存储空间,kylin 也使用了相同的方法,只不过使用了字典树(Trie
树),每一个维度的字典树作为 cube 的元数据以二进制的方式存储在 hbase 中,内存中也