背景
最近在整合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
解決辦法
- 直接修改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