Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient报错,问题排查

背景

最近在整合pyspark与hive,新安装spark-2.3.3以客户端的方式访问hive数据,运行方式使用spark on yarn,可是在配置spark读取hive数据的时候,这里直接把hive下的hive-site.xml复制到spark目录下,启动了一次spark,上面的问题就出现了。

网上的说法:

hive元数据问题,须要从新初始化hive的元数据
可是这个方法确定不适合我,由于仓库里的表不能受影响,上千张表呢,若是初始化了,全部表都要从新建立。

排查过程

* 首先查看服务器上/tmp/${user}/hive.log文件,这个是公司服务器当时配置的详细的hive执行日志。
 在日志中,有一段报错:
2019-07-06T10:01:53,737 ERROR [370c0a81-c922-4c61-8315-264c39b372c3 main] metastore.RetryingHMSHandler: MetaException(message:Hive Schema version 3.1.0 does not match metastore's schema version 1.2.0 Metastore is not upgraded or corrupt)
        at org.apache.hadoop.hive.metastore.ObjectStore.checkSchema(ObjectStore.java:9063)
        at org.apache.hadoop.hive.metastore.ObjectStore.verifySchema(ObjectStore.java:9027)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
这里的意思是,hive的版本是3.1.0,可是元数据中的版本信息是1.2.0,所以报错。

* 到hive的元数据库里查了下version表里的数据,确实版本是1.2.0

问题缘由

这里猜想,spark在读取hive元数据的时候,由于spark是直接从官网上下载的,可能官网上的spark是用hive1.2.0版本编译的,因此,它默认使用的1.2.0,致使在启动的时候,修改了hive的元数据

可是具体的缘由还不知道 下面会拿官网上的spark源码手动编译测试一下java

解决办法

  1. 直接修改version表的数据
select * from version;
update VERSION set SCHEMA_VERSION='2.1.1' where  VER_ID=1;

二、在hvie-site.xml中关闭版本验证sql

<property>
    <name>hive.metastore.schema.verification</name>
    <value>false</value>
</property>

深刻研究

在spark官网上查看了相关的资料,发现,在官网上下载的spark安装包,默认编译的hive版本是1.2.1的,因此每次启动spark的时候,会检查hive的版本。若是采用hive的默认配置,若是不同,

就会修改version 一开始尝试着下载spark源码从新编译spark安装包,编译执行hive的版本为3.1.1,可是,发现每次指定hive的版本,maven下载依赖的时候,都会报错。 报错信息以下:shell

后来想了个折中的办法,spark仍是使用原始版本,可是修改一下hive-site.xml文件。 注意:这里修改的是spark的conf下的hive-site.xml,原始的hive里的不须要修改数据库

<property>
    <name>hive.metastore.schema.verification</name>
    <value>true</value>
    <description>
      Enforce metastore schema version consistency.
      True: Verify that version information stored in metastore matches with one from Hive jars.  Also disable automatic
            schema migration attempt. Users are required to manually migrate schema after Hive upgrade which ensures
            proper metastore schema migration. (Default)
      False: Warn if the version information stored in metastore doesn't match with one from in Hive jars.
    </description>
  </property>
  <property>
    <name>hive.metastore.schema.verification.record.version</name>
    <value>false</value>
    <description>
      When true the current MS version is recorded in the VERSION table. If this is disabled and verification is
       enabled the MS will be unusable.
    </description>
  </property>

这两个配置,hive.metastore.schema.verification若是设置为true,那么每次启动hive或者spark的时候,都会检查hive的版本。为false,则会告警 hive.metastore.schema.verification.record.version若是设置为true,每次启动spark的时候,若是检查了hive的版本和spark编译的版本不一致,那么就会修改hive的元数据apache

这里的修改须要设置hive.metastore.schema.verification=false 且hive.metastore.schema.verification.record.version=false 如过这两个都为true,那么spark会修改hive元数据 若是hive.metastore.schema.verification=true,而且hive.metastore.schema.verification.record.version=false,这时候启动spark就会报错:服务器

Caused by: MetaException(message:Hive Schema version 1.2.0 does not match metastore's schema version 3.1.0 Metastore is not upgraded or corrupt)
	at org.apache.hadoop.hive.metastore.ObjectStore.checkSchema(ObjectStore.java:6679)
	at org.apache.hadoop.hive.metastore.ObjectStore.verifySchema(ObjectStore.java:6645)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

若是设置hive.metastore.schema.verification=false 且hive.metastore.schema.verification.record.version=true,spark仍是会修改hive的元数据 maven

因此,只要设置hive.metastore.schema.verification.record.version=false就能够了,可是为了保险起见,我两个都设置成false了oop