折腾了一天,终于解决了上节中result3的错误。至于为什么会产生这个错误,这里,先卖个关子,先看看这个问题是如何发现的:
首先,找到了这篇文章:http://apache-spark-user-list.1001560.n3.nabble.com/SparkSQL-select-syntax-td16299.html 里面有这么一段:
The issue is that you're using SQLContext instead of HiveContext. SQLContext implements a smaller subset of the SQL language and so you're getting a SQL parse error because it doesn't support the syntax you have. Look at how you'd write this in HiveQL, and then try doing that with HiveContext.
In fact, there are more problems than that. The sparkSQL will conserve (15+5=20) columns in the final table, if I remember well. Therefore, when you are doing join on two tables which have the same columns will cause doublecolumn error.
这里提及到两点:(1)使用HiveContext;(2)也就是导致这个错误的原因。
好吧,说到使用HiveContext,那咱就用HiveContext(尼玛,这里折腾了半天):
首先呢,看使用HiveContext都需要哪些要求,这里参考了这篇文章:http://www.cnblogs.com/byrhuangqiang/p/4012087.html
文章中有这么三个要求:
1、检查$SPARK_HOME/lib目录下是否有datanucleus-api-jdo-3.2.1.jar、datanucleus-rdbms-3.2.1.jar 、datanucleus-core-3.2.2.jar 这几个jar包。
2、检查$SPARK_HOME/conf目录下是否有从$HIVE_HOME/conf目录下拷贝过来的hive-site.xml。
3、提交程序的时候将数据库驱动程序的jar包指定到DriverClassPath,如bin/spark-submit --driver-class-path *.jar。或者在spark-env.sh中设置SPARK_CLASSPATH。
那咱就按照要求配置,可是,配置完成之后报错(交互模式):
Unable to instantiate org.apache.hadoop.hive.metastore.HiveMetaStoreClient
初步判断,是hive连接源数据库这块的问题,于是在hive-site.xml文件中添加连接源数据库的参数:
<property>
<name>hive.metastore.uris</name>
<value>thrift://111.121.21.23:9083</value>
<description></description>
</property>
指定好参数之后,满怀期待的执行了个查询,尼玛又报错(这个错误纠结了好久):
ERROR ObjectStore: Version information not found in metastore.
这个错误说的是,在使用HiveContext时,需要访问Hive的数据源,获取数据源的版本信息,如果获取不到,此时就会抛出该异常。关于解决方案网上倒是挺多,需要添加参数到hive-site.xml文件:
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
<description></description>
</property>
添加完参数,重启了Hive服务,执行Spark 的HiveContext,依旧报改错。使用IDE将程序编译打包后,放在服务器上执行:
#!/bin/bash
cd /opt/huawei/Bigdata/DataSight_FM_BasePlatform_V100R001C00_Spark/spark/
./bin/spark-submit \
--class HiveContextTest \
--master local \
--files /opt/huawei/Bigdata/hive-0.13.1/hive-0.13.1/conf/hive-site.xml \
/home/wlb/spark.jar \
--archives datanucleus-api-jdo-3.2.6.jar,datanucleus-core-3.2.10.jar,datanucleus-rdbms-3.2.9.jar \
--classpath /opt/huawei/Bigdata/hive-0.13.1/hive-0.13.1/lib/*.jar
无奈,又报另一个错(真是崩溃!):java.net.UnknownHostException: hacluster
这是hadoop的dfs.nameservices
嗯,不能解析主机名hacluster抛出的异常,那么继续,网上给的结果是:
需要把配置hdfs-site.xml复制到spark的conf目录下,果然,复制完成后,程序打成的jar包终于能在服务器上成功运行了。
但是回想起来,那么这个错误:ERROR ObjectStore: Version information not found in metastore.
到底是由于什么原因导致的?执行jar包和shell模式有什么区别呢?
继续,使用shell模式执行基于HiveContext的SQL,还是报这个错,那么,打开spark的debug看看有什么有价值的信息,找个许久,没有发现任何有价值的日志。继续在网上搜索,网上的这个问题,都是WARN级别的,而我的是ERROR级别的。
到这里,实在是没有什么思路了。哎,既然我的jar包能够执行成功,那么就看看使用jar包执行和该模式有什么区别?
首先想到的是,为什么hive-site.xml的参数:hive.metastore.schema.verification 没有生效?我重启服务了呀,是不是没有引用到该参数?!
哎,那我就添加HIVE_HOME环境变量,执行了一下,还是没生效,也就是说没有引用到该参数。。。已经濒临崩溃,过了许久,突然想到,我执行的spark-shell命令来源于哪?那么看一下:which spark-shell
好像发现了什么,该spark-shell是来自spark客户端程序的bin目录(之前为了使用命令方便,设置和了环境变量---华为的产品),也就是说,我默认的环境变量是指向spark客户端程序目录的!!!
终于找到了问题的根本,于是,将hive-site.xml、hdfs-site.xml复制到客户端程序的conf目录下,重启hive服务,一切OK!
过了一会,还有点不放心,到底是不是这个问题导致的呢?好吧,那么就在其他节点上测试了一下,首先客户端程序目录中没有该参数,执行失败,添加后,hive.metastore.schema.verification是生效的!
大功告成!整个过程,spark的debug功能一直是打开的,但是在日志中没有发现有价值的信息。
对了,要想使用IDE调试Spark的HiveContext程序,需要在main目录下添加resource目录(类型为Resources),并且将hive-site.xml、hdfs-site.xml添加到该目录中。
并且将三个驱动包引入:
datanucleus-api-jdo-3.2.6.jar,datanucleus-core-3.2.10.jar,datanucleus-rdbms-3.2.9.jar
差点忘了,我是为了解决上节中的result3问题,哈哈,这个问题其实是由于SparkSQL对SQL语法支持的问题。可以考虑使用其他方式(不在IN里面嵌套子查询),比如设置多个RDD或者左右连接等(有待测试)。
下节,大概说下Scala IDE如何配置(这个问题在清明假期折腾了两天,总结了两种方式)
转载于:https://blog.51cto.com/snglw/1634438