Apache Kylin是一个开源的分布式分析引擎,是大数据集大成者。所谓集大成者,就是把大数据里面的基础组件都用了个遍,Hive、MapReduce、HBase,HDFS,YARN,Zookeeper这些。大数据计算都比较耗时,Kylin采用预计算的方式来换取更快的速度,是典型的以空间换时间思想,使用资源越多,查询延迟越低。
cube构建时默认会按照设置的维度组合构建出全部的聚合结果,一共有2^n个结果,结果集太大并且不是所有维度的组合结果都会用到,因此结合业务场景权衡时间和空间,通过设置相关的构建条件,通过优化减少预聚合的结果集,提高资源利用率。可以优化的方面有以下几点:
剪枝优化
使用衍生维度
在维度表中,如果其他维度可以通过一个维度推导出来,那么就可以使用衍生维度优化。比如有这样的维度表:
1.时间、年、月、周、日;
2.电影id、电影名称、导演;
3.班级id、班级名称、班主任。
通过一个字段可以推断出另外一个字段,那么就可以使用衍生维度。设计cube时如下配置即可:
聚合组
如果有A、B、C、D四个维度,查询的时候只会用到(A,B)或者(C,D)维度做组合查询,那么就可以设置聚合组优化。下图是添加了两个聚合组的示例:
在聚合组中还可以细分设置必需维度、层级维度、联合维度进一步剪枝。
必需维度
查询的时候如论如何也会带上的查询维度,可以设置为必要维度;反过来考虑,如果从来没有用到的维度,也不需要参加构建cube。
层级维度
如果维度之间有层级关系,典型的例子是:
1.国家-省份-城市;
2.总部-分公司-业务部门;
3.小区-楼栋-楼层。
那么可以设置层级维度减少构建的cuboid数量,注意层级范围从大到小。
联合维度
对于同时group by 几个维度的查询,可以设置联合维度剪枝。
设置示意图如下:
并发粒度优化
kylin的每一次构建cube都会生成一个segment,当segment的某一个cuboid大小超出限制阈值时,会将该cuboid的数据分片到多个分区,以实现并行读取提高查询速度。通过如下参数控制:
kylin.hbase.region.cut :分区大小,默认是5.0G,决定需要多少个分区。假设50G的segment,将会有10个分区。
kylin.hbase.region.count.min :最小分区数量,默认是1,
kylin.hbase.region.count.max :最大分区数量,默认是500
通常会根据cube设置独立的并发粒度。如果有50G的segment,kylin.hbase.region.count.min 设置为2,kylin.hbase.region.count.max设置为100,kylin.hbase.region.cut 调整为1,该Segment会被分配到50个分区,相比默认设置,我们的Cuboid可能最多会获得5倍的并发量。
设置示例如下:
Rowkey优化
调整Rowkey顺序
在调整Rowkey的顺序时需要遵循以下几个原则:
第一:有可能在查询中被用作过滤条件的维度,应当放在其他维度的前面。
- 对于多个可能用作过滤条件的维度,基数高的(意味着用它进行过滤时,较多的行被过滤,返回的结果集较小)更适合放在前面;
- 总体而言,可以用下面这个公式给维度打分,得分越高的维度越应该放在前排:排序评分=维度出现在过滤条件中的概率*用该维度进行过滤时可以过滤掉的记录数。
第二:将经常出现在查询中的维度,放在不经常出现的维度的前面,这样,在需要进行后聚合的场景中 查询效率会更高。
第三:对于不会出现在过滤条件中的维度,按照其基数的高低,优先将低基数的维度放在Rowkey的后
面。这是因为在逐层构建Cuboid、确定Cuboid的生成树时,Kylin会优先选择Rowkey后面的维度所在
的父Cuboid来生成子Cuboid,那么基数越低的维度,包含它的父Cuboid的行数就越少,聚合生成子 Cuboid的代价就越小。
按维度分片
kylin存储cuboid时会进行分片处理,默认情况下会对所有列进行hash随机分片,不能控制cuboid保存到哪里。使用特定维度分片,一定能让该维度值一样的数据都在一起。
Cube Planner优化
Cube Planner是一个自动优化器,在用户手动优化的基础上,根据cuboid的查询统计数据,减少少使用的cuboid,提前预计算经常使用的cuboid,提高cube的命中率。
自动创建系统cube
从kylin 2.6.0开始提供system-cube.sh脚本,用户可以通过执行此脚本来自动创建系统cube。
创建系统cube:sh system-cube.sh setup
构建系统cube:sh bin/system-cube.sh build
为系统cube添加定时任务:bin/system.sh cron
官方文档:http://kylin.apache.org/docs/howto/howto_optimize_cubes.html