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的版本中,會徹底解決這個問題。