Apache Kylin增量构建

96
若愚先生L
2018.11.28 18:49* 字数 1085

前提条件:

事实表中必须有一个时间类型的字段。这个时间字段最好是Hive表的分区字段。

构建设置

Model层面的设置

设置分区字段Partition Date Column:分区时间字段只能来源于事实表,并且是时间类型
设置分区字段时间格式Date Format:按照分区字段的时间格式来选择


设置Partition
Cube层面的设置

Cube每次增量构建都会生成一个Segment,随着时间的推移,当前Cube会存在大量的Segment,这时候会产生以下两个问题:
1、执行查询时查询引擎要聚合多个Segment的结果才能返回正确的查询结果,聚合的Segment越多,查询的性能越差。
2、每个Segment都对应Hbase的一张表,过多的Segment会在底层的存储系统产生大量的文件,会给存储系统HDFS NameNode带来压力。

我们要在Cube层面进行以下设置来让Kylin按照一定的规则自动合并Segment:
设置之前先了解Segment的两个特性:
①Segment都有两个属性,分别为开始时间StartDate和结束时间EndDate,遵循左闭右开原则。
②Segment之间是连续的,也就是说上一个Segment的EndDate等于下一个Segment的StartDate。

设置Auto Merge Thresholds:合并的阈值可以设置多个层级,当最大阈值不能满足时,尝试下一个稍小的阈值
设置Volatile Range:如何你不想Kylin自动合并最近某个时间段的Segment,可以设置改属性。比如设置为30,代表Kylin不会自动合并最近30天所包含的所有Segment。
设置Retention Threshold:如果你想只保留最近1年的Segment中的数据,可以设置该值为365。
设置Partition Start Date:一般为事实表中时间最老的那条数据的时间。

设置刷新

触发增量构建

完成上面的设置以后,在Kylin的WebUI上面我们可以手动触发增量构建,右键Actions,选择build:如你所见,每次增量构建时都会产生一个Segment,每个Segment都需要设置StartDate和EndDate。


手动触发增量构建

但我们一般很少这样做,我们更希望程序能帮我自动触发增量构建,Kylin为我们提供了基于HTTP方式的API,下面有一种方法可以借鉴:
Kylin是从Hive中来拉取原始数据的,当我们增量的数据通过ETL进入Hive以后,可以紧接着在ETL脚本中发起一个增量构建的HTTP请求:
curl -X PUT -H "Authorization: Basic YmklM0FiaTEyMw==" -H 'Content-Type: application/json' -d '{"endTime":"{endTime}", "startTime":"{startTime}", "buildType":"BUILD"}' http://localhost:7070/kylin/api/cubes/{cubeName}/rebuild
在脚本中保存上一次构建的endTime,作为此次构建的startTime,此次构建的endTime可以设置为ETL中按时间段抓取数据的结束时间,并保存此次构建的endTime作为下次构建的startTime。

一些思考

我们知道Kylin是从Hive中拉取原始数据的,Hive作为数据仓储,存储的数据是稳定的。在很多场景中我们会有增量更新的需求,Kylin是支持增量更新的,但有个前提条件是Hive中的数据已经更新完成。有时候Hive表中的某个分区的数据由于清洗出错,重新清洗,重新导入后,可以刷新这个分区对应的Segment来重新拉取数据构建。基于这个思路,每次增量更新的时候,只要找到更新数据所在的所有Segment,然后刷新即可。
但Kylin真的适合增量更新构建吗?首先Kylin的数据源Hive的数据更新的代价很大,数据更新也违背了Hive数据仓库的设计初衷。其次Kylin刷新Segment的代价同样很大。
所以遇到增量更新的需求,我们可以换一种方式来实现,比如HBase。

Kylin