微信搜索lxw1234bigdata | 邀请体验:数阅–数据管理、OLAP分析与可视化平台 | 赞助作者:赞助作者

Saiku结合Hive做大数据多维数据分析

Hive lxw1234@qq.com 25720℃ 6评论

前面介绍了将Saiku和Kylin结合起来做OLAP多维分析,Saiku也支持多种其他数据源,如MySQL,JDBC等,本文介绍将Saiku和Hive结合起来使用的方法,并解决期间遇到的问题。

注:Saiku社区版(Saiku CE)的下载地址为:

http://community.meteorite.bi/?cedownload

Saiku与Hive

Saiku最新的社区版本中自带的Hive版本为0.13.1,我使用的Hive版本也为0.13.1,Saiku通过JDBC与HiveServer连接。

启动HiveServer2

注意:启动HiverServer2时候,可以后台运行,并将日志重定向到一个文件中,方便查看:./hiveserver2 >> /tmp/hiveserver.log 2>&1 &

启动Saiku

新建mondrian schema

基于Hive中已有的事实表lxw1234_kylin_fact(该表是之前为kylin创建的,这里直接使用,和表名无关)创建Schema:

hive> desc lxw1234_kylin_fact;
OK
day                     date
cookieid                string
region                  string
city                    string
siteid                  string
os                      string
pv                      bigint

vi ad_schema2.xml

<?xml version="1.0"?>
<Schema name="ad_schema2">  
<Cube name="lxw1234_ad_cube_hive">  
    <!-- 事实表(fact table) -->  
    <Table name="lxw1234_kylin_fact" />  
    <Dimension name="地域">  
        <Hierarchy hasAll="false">  
            <Table name="lxw1234_kylin_fact"></Table>  
            <Level name="省份" column="region" table="lxw1234_kylin_fact"></Level>
            <Level name="城市" column="city" table="lxw1234_kylin_fact"/>
        </Hierarchy> 
    </Dimension>  
  
    <Measure name="曝光数" column="pv" aggregator="sum" datatype="Integer" />
</Cube>  
</Schema>

这里只取了两个维度,省份和城市,一个指标PV。

将schema文件上传到Saiku。

新建Hive数据源

saiku

创建一个名为hive_ds的Hive JDBC数据源。

Hive-JDBC的错误

当进入到Home页,点击创建新查询之后,在多维数据集里面没有刚才新建的数据源hive_ds,查看saiku后台日志,发现以下错误(这里一并列出):

错误1:

ERROR [SecurityAwareConnectionManager] Error connecting: hive_ds
mondrian.olap.MondrianException: Mondrian Error:Internal error: while quoting identifier
Caused by: java.sql.SQLException: Method not supported
   at org.apache.hive.jdbc.HiveDatabaseMetaData.getIdentifierQuoteString
   (HiveDatabaseMetaData.java:342)

该错误是由于Mondrian中使用了hive-jdbc未实现的方法:getIdentifierQuoteString,hive-jdbc-0.13.1.jar源码中该方法为:

public String getIdentifierQuoteString() throws SQLException {
    throw new SQLException("Method not supported");
}

错误2:

ERROR [SecurityAwareConnectionManager] Error connecting: hive_ds
mondrian.olap.MondrianException: Mondrian Error:Internal error: while detecting isReadOnly
Caused by: java.sql.SQLException: Method not supported
        at org.apache.hive.jdbc.HiveDatabaseMetaData.isReadOnly
      (HiveDatabaseMetaData.java:762)

错误原因同上。

解决的方法,需要修改hive-jdbc-0.13.1.jar中的源码org.apache.hive.jdbc.HiveDatabaseMetaData,将上面的两个方法改为:

public boolean isReadOnly() throws SQLException {
	 return false;
}
public String getIdentifierQuoteString() throws SQLException {
	  return " ";
}

注意,要快速修改源码,不要整个编译工程,通常我的做法是引入相关的jar包,这里需要引入hive-jdbc-0.13.1.jar 和 hive-metastore-0.13.1.jar ,然后新建一个package和源文件的package相同:org.apache.hive.jdbc , 再将源码 HiveDatabaseMetaData.java 拷贝到该package下进行修改,修改好后,将该类相关的class文件,替换到 hive-jdbc-0.13.1.jar 中即可。

用新的hive-jdbc-0.13.1.jar 替换Saiku中的jar包,位置在:~/saiku/saiku-server/tomcat/webapps/saiku/WEB-INF/lib下。

重启Saiku Server。

创建查询

重启后,再次进入创建查询页面,后台没有报错,多维数据集下已经有了hive_ds。选择维度和指标后,saiku生成查询语句,并通过JDBC提交查询到Hive。

saiku的日志:

saiku

另外,HiveServer2的日志中也有MapReduce运行日志产生。

但通过日志可以看到,这个简单的查询,貌似被分成好几步来执行查询,最后耗时87秒。

saiku

Hive查询过程分析

从ResourceManager的页面上看到,一共提交了三个SQL:

saiku

第一个SQL为:

SELECT
lxw1234_kylin_fact.region as c0, 
lxw1234_kylin_fact.city as c1 
FROM lxw1234_kylin_fact as lxw1234_kylin_fact 
GROUP BY lxw1234_kylin_fact.region,lxw1234_kylin_fact.city 
ORDER BY CASE WHEN lxw1234_kylin_fact.region IS NULL THEN 1 ELSE 0 END,lxw1234_kylin_fact.region ASC,
CASE WHEN lxw1234_kylin_fact.city IS NULL THEN 1 ELSE 0 END,lxw1234_kylin_fact.city ASC

作用是从事实表中抽取所有维度并去重排序。

第二个SQL为:

SELECT count(DISTINCT city) FROM lxw1234_kylin_fact

看上去是获取所有city的不重复数。

第三个SQL为:

SELECT
lxw1234_kylin_fact.region as c0,
lxw1234_kylin_fact.city as c1,
SUM(lxw1234_kylin_fact.pv) as m0 
FROM lxw1234_kylin_fact as lxw1234_kylin_fact 
GROUP BY lxw1234_kylin_fact.region,
lxw1234_kylin_fact.city

发现这个SQL才是最终显示结果要用的查询,那么前两个的作用是什么呢?

看下面的操作:

saiku

点击省份维度之后,便弹出筛选对话框,里面列出了所有的省份名称,点击城市维度之后也是如此,前两个SQL的用途便在这里,从事实表中提取出所有维度缓存起来,供筛选使用。

另外,Saiku对于Hive的查询结果也会缓存,这样,在做分析查询的时候,能从缓存中获取的数据便不会再从Hive中查询,可以试试,过滤几个省份,获取去掉城市维度,结果立刻就返回,并不是从Hive中查询,这点,使得Saiku+Hive的可行性增强了不少。

接下来就尝试使用Saiku和SparkSQL结合使用,效率应该比Hive好很多。请持续关注 “lxw的大数据田地” .

 

 

如果觉得本博客对您有帮助,请 赞助作者

转载请注明:lxw的大数据田地 » Saiku结合Hive做大数据多维数据分析

喜欢 (26)
分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(6)个小伙伴在吐槽
  1. 测过saiku+mysql、saiku+sparkSQL、saiku+kylin,从性能角度看,也就kylin能用
    星爷2016-05-15 07:33 回复
    • 请教一下,Saiku+Kylin中怎么解决只能内关联和COUNT DISTINCT类的指标?
      lxw1234@qq.com2016-05-16 13:30 回复
      • COUNT DISTINCT倒是很好解决,内联比较麻烦。
        moodmass2016-07-29 13:39 回复
  2. 博主,SparkSQL结合使用的案例 什么时候出啊?
    spark2016-06-03 13:00 回复
  3. 博主什么时候出saiku + SparkSQL的呀,最近在研究出问题一直没有解决
    无重力2017-06-01 16:41 回复
  4. 请问后面有实现saiku连接spark sql吗
    breezekill2018-01-10 15:48 回复