Spark-SQL读不到Hive数据库的新坑指北

7,565 阅读3分钟

源自博客: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的配置

  1. 将原spark里的hive-site.xml备份或删掉,将hive安装目录下的hive-site.xml拷贝到spark conf下

还是拷贝,但是Ambari用户安装集群时hive-site.xml是已经在spark里存在的,并且之前hive低版本不存在该问题,可能令人困惑。

  1. 再次启动spark-sql,如果报tez相关的错误,则直接将hive-site.xml中所有tez的配置删除即可!
  2. 正常启动spark-sql,show databases;(可能还有rootspark用户权限问题) 能够正常显示我在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官网文档两个链接: