spark hive java.lang.NoSuchFieldError: HIVE_STATS_JDBC_TIMEOUT

时间:2023-03-10 07:27:31
spark hive java.lang.NoSuchFieldError: HIVE_STATS_JDBC_TIMEOUT

java.lang.NoSuchFieldError: HIVE_STATS_JDBC_TIMEOUT

这个问题我感觉是hive给spark挖的一个大坑。spark版本是2.4.4,hive是3

这个问题,基本发生在远程启动spark客户端,并且访问spark集群,然后再连接hive造成的。因为,无论升级到spark的什么版本,用hive的什么版本,在集群环境下直接启动spark-sql或者spark-shell访问hive都不会发生这个问题。只有在用代码集成hive-jdbc,spark-core,spark-sql,spark-hive等依赖的时候,就会报出这么一个问题。

导致这个问题的原因如下:用代码启动spark,并且连接spark standalone 或者yarn模式spark-client方式的时候,本地机器会成为driver,diver负责向hive通信。代码在通信的过程中,需要依赖hive相关的jar包。在连接hive之前,spark会进行一下连接相关参数的检查,检查的参数来自于hive的jar包,其中就有这么一个:HIVE_STATS_JDBC_TIMEOUT。然而,spark集群下面依赖的hive的jar包还是1.2.1版本的,所以集群模式连接hive没有问题。然后hive升级到了2之后的版本,hive去掉了这个参数(大家可以现在去spark的github上面看看最新的代码,里面已经做了相关修改,但是命名还是:hardcode。),然后spark-sql里面的代码依然是要调用hive的这个参数的,然后就报错了。

这个问题在jira上说加上 spark.sql.hive.metastore.jars  spark.sql.hive.metastore.version这两个参数(当然这两个参数还是要加的),然后这两个参数并不能解决这个问题,因为在用到这两个jar包之前,spark就已经对连接hive参数进行了检测。

所以最终解决办法是:在spark 2.4.4的代码中,删除掉HIVE_STATS_JDBC_TIMEOUT以及另外一个参数,然后重新编译spark-hive的jar包。再 将此jar包替换现有的spark-hive的jar包。

最后,应该是在spark3的版本中,会彻底解决这个问题。