源自博客:kelvin-qzy.top/ 欢迎访问
背景
本文讲的是spark-sql
这个命令行工具读取hive数据的情况:
- Spark是2.3.1,HDP发行版
- Hive是3.1.0,HDP
- SparkSQL和Hive3的交互问题,用Sparksql读取处理hive中已存在的表数据但读取不到hive的database
- 顺便,SparkSQL读取不了hive内部表,可以读hive外表的数据,文末有解决方案
刚开始熟悉Spark与hive3.x的交互,搜索了一番没有找到解决方案,大都是说把hive-site.xml拷贝到spark目录下,实际上我的集群安装时这个是自动进行的,可以看到spark的conf下已经有hive-site.xml文件了。
关键日志
INFO HiveUtils: Initializing HiveMetastoreConnection version 3.0 using file
INFO HiveConf: Found configuration file file:/xxx/hdp/current/spark2/conf/hive-site.xml
INFO HiveClientImpl: Warehouse location for Hive client (version 3.0.0) is /apps/spark/warehouse
INFO HiveMetaStoreClient: Opened a connection to metastore, current connections: 1
INFO HiveMetaStoreClient: Connected to metastore.
此时spark-sql是正常启动的,有配置文件且显示正常连接到了hive metastore,关键词有:
- HiveMetastoreConnection version 3.0
- Hive client (version 3.0.0)
- Connected to metastore
这时在命令行输入show databases;
并执行,结果如下:
问题
结果中只有default数据库,并无其他hive中已创建好的数据库,读取并处理更无从谈起。而期望是能显示hive中的其他多个数据库名称。
解决方案
排查hive-site.xml
注意到启动过程中打印的消息,INFO HiveConf: Found configuration file file:/xxx/hdp/current/spark2/conf/hive-site.xml
,这里提到了一个hive的配置文件,检查配置文件的内容:
注意到上述端口,与HiveServer实际使用的端口是不一样的! 推测可能是新版本的集成包中,spark采用了一套独立的配置,因而可以正常启动,但读取不到hive的数据库。
版本提示
注意INFO的信息:HiveMetastoreConnection version 3.0
,相关提示都是说版本为hive3.x,根据小伙伴的反映,在之前hive2.x版本时spark-sql读取hive的数据表毫无障碍,因此待考证是版本升级的变动!
实际解决(临时方案)
直接拷贝hive的配置
- 将原spark里的hive-site.xml备份或删掉,将hive安装目录下的hive-site.xml拷贝到spark conf下!
还是拷贝,但是Ambari用户安装集群时hive-site.xml是已经在spark里存在的,并且之前hive低版本不存在该问题,可能令人困惑。
- 再次启动spark-sql,如果报tez相关的错误,则直接将hive-site.xml中所有tez的配置删除即可!
- 正常启动spark-sql,
show databases;
(可能还有root
或spark
用户权限问题) 能够正常显示我在hive中创建的其他数据库了。
或 修改spark自带的hive-site.xml
直接修改以下三项为:
<property>
<name>hive.server2.thrift.http.port</name>
<value>10001</value>
</property>
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<property>
<name>metastore.catalog.default</name>
<value>hive</value>
</property>
spark使用与hive一样的thrift和metastore就可以了。
注意
- 似乎还有读取hive内部表和外部表的问题(见后文补充)。
2019-10-11补充: Hive在HDP-3.0中引入了重大改进,包括性能和安全性改进以及ACID适用性。Spark无法读取或写入ACID表,因此为了适应这些改进,引入了Hive catalogs和Hive Warehouse Connector(HWC)。
重要补充!Spark读取Hive3.0内表(2019-10-04)
补充Spark读取不了hive内部表数据的原因:
-
HDP3.0 集成了hive 3.0和 spark 2.3.1,spark读取不了hive表的数据,准确来说是内表(hive管理表)的数据。
-
hive 3.0之后默认开启ACID功能,而且新建的内表默认是ACID表(hive事务表)。而spark目前还不支持hive的ACID功能,因此无法读取ACID表的数据。
-
参考Spark Issue:SPARK-15348 Hive ACID
临时的解决办法
临时应对如下, 修改Hive以下参数让新建的表默认不是acid表。
hive.strict.managed.tables=false
hive.create.as.insert.only=false
metastore.create.as.acid=false
这对已存在的内部表无效!
HDP文档的解决方案:
经@YangGod同学指点,官网给出的一种解决方案是使用
Hive Warehouse Connector
,但这个方案应该也不是很完美,有试过的同学可以说一下好不好用。
HDP官网文档两个链接: