Cube的其他优化
并发粒度控制
- 当Segment中某一个Cuboid的大小超过一定的阈值时, 系统会将该Cuboid的数据分片到多个分区中, 以实现Cuboid数据读取的并行化, 从而优化Cube的查询速度
- 每个Cube可以单独进行配置
参数设置:
- kylin.hbase.region.cut: 默认值5.0, 单位GB, 指定了每个分区的大小
- kylin.hbase.region.count.min: 默认值1, 指定了每个Segment最少被划分成多少个分区
- kylin.hbase.region.count.max: 默认值500, 指定了每个Segment最多被划分成多少个分区
Rowkeys优化
- Cube的每个Cuboid中都包含了大量的行,每个行又分为Rowkeys和Measure部分
- 每行Cuboid数据中的Rowkeys都包含当前Cuboid中所有维度值的组合
维度编码
编码代表了该维度的值应使用何种方式进行编码, 合适的编码能够减少维度对空间的占用
Kylin目前支持以下几种编码方式:
- Date编码: 将日期类型的数据使用三个字节进行编码, 其支持从0000-01-01到9999-01-01中的每一个日期
- Time编码: 仅支持表示从1970-01-01 00:00:00到 2038-01-19 03:14:07的时间, 但是会丢失毫秒信息
- Integer编码: 长度为1~8, 用来编码整数类型的维度, 提供额外参数
Length
- Dict编码: 为维度所有可能的值创建字典, 使用字典中每个值的编号来编码
产生的字典是在查询时加载入构建引擎和查询引擎的, 所以在维度的基数大、长度也大的情况下, 容易造成构建引擎或查询引擎的内存溢出
- Fixed_length编码: 以固定长度的字节来存储代表维度值的字节数组, 该数组为字符串形式的维度值的UTF-8字节
如果维度值的长度大于预设的Length, 那么超出的部分将会被截断
按维度分片
- 默认情况下Cuboid的分片策略是随机的
- Cuboid的每个分片都会被分配到存储引擎的不同物理机器上
- 在读取Cuboid数据的时候, HBase会为每个Region开启一个Coprocessor实例来处理查询, Coprocessor能够在返回结果之前先对当前的分片数据做一定的聚合处理
- 按照特定的维度分片, 那么各个分片上不会有相同的该维度值
- 每个物理分区在聚合处理后返回的结果数量大大减少
- 各个分片的结果返回到查询引擎后,因为相同的维度值基本已经完成聚合处理, 所以查询引擎无需再做聚合
调整Rowkeys顺序
- Kylin会把所有的维度按照顺序黏合成一个完整的Rowkeys, 并且按照这个Rowkeys升序排列Cuboid中的所有行
- 如果在一个比较靠后的维度上有过滤条件, 只能依靠HBase的FuzzyKeyFilter, 一旦前面维度的基数很大, 付出的代价将会很高
Rowkeys的顺序调整原则:
- 在查询中被用作过滤条件的维度尽可能放在其他维度的前面
- 将经常出现在查询中的维度放在不经常出现的维度前面
- 对于基数较高的维度, 如果查询会有这个维度上的过滤条件, 那么将它往前调整; 如果没有, 则向后调整