上节用Hive UDTF平铺内嵌类型字段介绍了接入Kylin前如何处理Hive中的复杂字段,不过每次在cube build前进行一次数据处理,存到中间表,再接入该中间表,这样的流程不仅低效繁琐而且耦合性强不易维护。
目前业界更流行的做法是通过Hive逻辑视图来处理。因为视图不需要物化,可以节省计算资源和存储空间,更重要的是减少环节降低了数据的延迟。试想本来每天凌晨1点就开始离线ETL任务,数据仓库的数据3点入库完毕可以进行cube build。如果预留1小时给中间表的计算环节,那么cube build要4点才可以开始,Kylin的下游任务全部都要顺延一个小时,这个成本是很高的。相比之下视图只会给cube build增加一点overhead,完全可以接受。
LateralView与UDTF
UDTF(User Defined Table Generating Functions)顾名思义是用于生成一张完整的表,而Hive对新表的结构并没有概念,所以UDTF只可以单独使用,不能直接和其他列一起出现在SELECT
子句中。要想达到上述效果,需要和LateralView配合使用。
根据官方文档LanguageManual LateralView,lateralView语法如下:
举个栗子:
如果要同时使用多个UDTF:
PARTITIONED VIEW
视图应该与数据源表同样是增量更新的,所以需要创建的是分区视图。根据官方文档PARTITIONED VIEW,语法如下:
创建PARTITIONED VIEW的语法与创建PARTITIONED TABLE的语法十分相似,不同之处在于VIEW使用PARTITIONED ON,而TABLE使用PARTITIONED BY。这是因为VIEW的分区列属于数据其中的一列,而TABLE的分区列实际上是元数据,由目录结构保存。因此VIEW的分区列只需要指定列名而不需要指定数据类型。此外,根据惯例VIEW的分区列需要按序出现在SELECT
子句的最后,否则会创建失败。
VIEW分区列与基表的分区列并不需要保持一致,实际上它们在逻辑层面完全没有联系,两者真正的关系是发生在VIEW的查询被翻译为底层基表的查询时,如果VIEW的分区列恰好是基本的分区列则会提高查询效率。因此对非分区基表创建分区视图是完全可能的。正由于这种灵活性,VIEW的分区信息需要用户自己管理,管理语句如下:
以每天增量cube build作例子,如果基表按天分区,需要在cube build之前将新分区先添加好。
总结
Hive逻辑视图的管理操作只涉及元数据,很轻量级,可以用于应对原始数据过滤条件变化等Kylin不擅长的需求改变。在Kylin和Hive仓库之间引入Hive视图层负责ETL操作可以给整个数据处理流程增加很大的灵活性。
参考文献
1.Apache Kylin高级部分之使用Hive视图
2.PartitionedViews
3.LanguageManual LateralView