首页 > 代码库 > Apache Kylin高级部分之使用Hive视图

Apache Kylin高级部分之使用Hive视图

本章节我们将介绍为什么需要在Kylin创建Cube过程中使用Hive视图;而如果使用Hive视图,能够带来什么好处,解决什么样的问题;以及需要学会如何使用视图,使用视图有什么限制等等。

 

1.      为什么需要使用视图

Kylin创建Cube的过程中使用Hive的表数据作为输入源。但是有些情况下,Hive中的表定义和数据并不能满足分析的需求,例如有些列的值需要进行处理,有些列的类型不满足需求,甚至有时候我们在创建Hive表时为了方便快捷,会将Hive表的所有列的字段类型都定义为string,因此很多情况下在使用Kylin之前需要对Hive上的数据格式等问题进行适当的处理。

 

但是如果在Hive中通过修改原表来解决上面的问题,比如使用alter table的方式修改原始表的Schema信息未免会对其它依赖Hive的组件有所影响(例如可能导致通过Sqoop等方式导入数据失败),而且也有可能导致之前的作业无法正常运行。于是我们需要考虑在不改变原表的情况下解决这个问题,因此我们想到的方案是使用Hive的视图。

 

当然,除了Hive数据源本身Schema等限制之外,Kylin对于Hive的使用还有一定的限制,这也间接的导致我们需要使用视图:

A.     同一个项目下使用相同表(可能根据不同的filter条件过滤,或者设置了不同的维度等)创建了不同的Cube,会导致查询的时候定位到错误的Cube等异常问题。

B.     只支持星型模型

我们的来源表可能包含多张事实表和多张维表,那么就需要将多张事实表整合成一张大的宽表。

 

2.      如何使用视图

Hive目前只支持逻辑视图,而我们需要的仅仅是对Hive原始的Schema信息的修改,而并非希望通过物化视图优化查询速度,因此目前Hive对视图的支持可以满足Kylin的需要。

 

下面根据不同的场景分别介绍一下如何创建视图作为Kylin的输入源:

A.     分表的情况

两个表具有相同的结构,但是保存不同的数据,例如一个表保存Android端的访问数据,一个访问iOS端的数据,那么就可以通过Hive的view解决。

 

例如有一个用户有两张表product_android和product_ios,这两个表具有相同的表结构,用户需要将平台(Android或者IOS)作为一个维度进行分析,因此我们为其创建了这样的view:

create view palearn_cube as
select userid, eventid, label, day, ‘android‘ as platformfrom palearn_android WHERE category=‘gc001‘
UNION ALL
select userid, eventid, label, day, ‘ios‘ as platform frompalearn_ios WHERE category=‘gc001‘;

这样可以将palearn_cube作为事实表来创建Cube,其中而platform作为其中的一个维度

 

B.     自定义函数

Kylin中使用Apache Calcite作为SQL的查询引擎,但是Kylin支持的自定义函数代价比较大,因此如果需要使用自定义函数,那么可以在Hive中创建视图来对字段进行处理。

C.     雪花模型的支持

目前Kylin仅支持星型模型,而通过在Hive中创建视图,我们可以很容易地把雪花模型转换为星型模型,甚至生成一个大的宽表。

 

D.     频繁修改表字段名

Kylin直接使用Hive中的字段名作为元数据,如果频繁修改事实表或者维度表的字段名会导致元数据错误(https://issues.apache.org/jira/browse/KYLIN-1173),因此通过视图增加一层映射是比较好的方法,这样可以使得原生的Hive表的字段名对Kylin的Cube透明,此后再需要修改字段名的时候不会对Cube有所影响,只需要修改view的定义。

 

E.      UHC维度

当一个维度的cardinality比较大时可能会出现的问题比较多,首先可能导致Extract Fact Table Distinct Columns这一步时导致reducer出现OOM;其次在创建维度字典树可能会导致维度字典树太大占据大量的内存;另外会导致cube的构建速度缓慢,占用大量的存储空间。此时就需要思考一下这样的UHC维度是否是必须的,是否可以提取出部分信息减小维度,例如timestamp维度,是否可以精确到5分钟,详细地址的维度,是否可以精确到县、镇,这样可以大大减小维度数,而且更详细的信息并没有太大的统计意义。例如url类型的维度,是否可以把参数去掉只保留访问路径。

 

F.      Hive中表字段类型变化

比如我们之前有一个需求计算一个指标的Count Distinct值,虽然这个字段存放的内容为整数值,但是Hive表字段类型为string,Kylin中Count Distinct聚合函数不支持字符类型,因此我们在Hive中创建视图解决这个问题,即将string类型转换为整数类型。

 

G.     复合数据类型处理

由于Hive中可以定义复杂的数据类型,例如map、struct,而Kylin中无法处理这种类型,所以需要使用视图将复杂类型字段进行拆分出维度和度量。

 

在我们目前的实践中,有一部分Cube依赖的事实表都是通过view创建的,这样增加了一层映射,可以减小cube对原始表的依赖,提高灵活性。

 

3.      使用视图限制

由于Hive的限制,Hive不能对view使用HCatalog获取数据

(https://issues.apache.org/jira/browse/HIVE-10851),因此当你在Kylin中load一个view的时候,Kylin计算表的cardinality的job无法获取到cardinality的值,这时就要求用户知道每一列的cardinality大致的情况,如果实在不确定可以到Hive里面查询一下。

 

4.      使用视图实战

这里我给朋友们简单演示一下视图的使用,其实视图在我们项目中还是会经常遇到的。

不知道朋友们还记不记得之前我们创建过三张表(请查看“Apache Kylin进阶部分之多维分析的Cube创建实战”章节):

事实表:kylin_flat_db.web_access_fact_tbl

维表:kylin_flat_db. region_tbl

维表:kylin_flat_db.city_tbl

 

如果您根据本书实战的话,当前Hive的kylin_flat_db数据库下面应该有这三张表。我们现在将在Hive中对这三张表创建视图,根据视图来构建Cube,大概步骤如下:

步骤一:创建视图

在Hive Cli中执行如下SQL:

use kylin_flat_db;
create view v_pvuv as select a.DAYas v_date,
       b.regionname,
       c.cityname,
       hash(a.cookieid) as cookieid,
       a.pv
from web_access_fact_tbl a
join region_tbl b
on a.regionid = b.regionid
join city_tbl c
on a.cityid = c.cityid;

这里对cookieid字段(字符串类型)使用hash函数处理,结果处理为整数类型,我们这样做的目的是为了使用Count Distinct(目前只支持整数类型)精确去重。

 

注:hash算法的特点是可重复和不可逆的,即针对不同的字符串进行hash处理,结果可能会重复的,所以上面的方法存在一定的问题。在实际项目中我们使用Hive自定义函数对需要使用Count Distinct精确的字段(整数类型就不必处理了)处理成整数类型。

 

步骤二:创建项目

创建“view_project”工程,当然也可以使用任何已经存在的工程。

 

步骤三:导入数据源

导入kylin_flat_db数据库下刚才创建的视图v_pvuv。

 

步骤四:创建Model

这里我们作为演示,只选了一张视图作为事实表,没有维表。其中:

维度字段:v_date,regionname,cityname

度量字段:cookieid,pv

分区字段:v_date

 

步骤五:创建Cube

因为朋友们对于如何创建Cube都很熟悉了,这里我们简要罗列几步。

 

创建Cube所选的维度如下:

技术分享


创建Cube所选的度量如下:

技术分享

其中我们使用精确的COUNT_DISTINCT函数来计算cookieid字段中值,所以返回类型为bitmap。

 

步骤六:构建Cube

设置构建的结束时间,然后构建Cube。

 

步骤七:查询Cube

查询如下SQL:

select v_date,
       regionname,
       cityname,
       count(distinct cookieid)
from V_PVUV
group by v_date,
         regionname,
         cityname;

 技术分享

结果为:

 技术分享

在我们使用Kylin的过程中,对于上面提到的问题很多都可以通过Hive的视图进行解决。如果朋友们在Kylin使用过程中遇到一些Kylin自身无法解决的时候,可以尝试一下Hive的视图,也许会给您带来惊喜。

Apache Kylin高级部分之使用Hive视图