背景
本文讲的是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
直接修改以下三项为:
hive.server2.thrift.http.port
10001
hive.server2.thrift.port
10000
metastore.catalog.default
hive
复制代码
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表的数据。
临时的解决办法
临时应对如下,
修改Hive以下参数让新建的表默认不是acid表。
hive.strict.managed.tables=false
hive.create.as.insert.only=false
metastore.create.as.acid=false
复制代码这对已存在的内部表无效!
HDP文档的解决方案:
经@YangGod同学指点,官网给出的一种解决方案是使用Hive Warehouse Connector,但这个方案应该也不是很完美,有试过的同学可以说一下好不好用。
HDP官网文档两个链接: