最近在使用 hive on spark的時候遇到了一個錯誤:
java.lang.ClassCastException: org.apache.hadoop.io.LongWritable cannot be cast to org.apache.hadoop.io.IntWritable
at org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableIntObjectInspector.get(WritableIntObjectInspector.java:36)
百思不得其解,最後在查閱相關資料(各種某度)的時候發現了問題,
有這麼一個參數:
spark.sql.hive.convertMetastoreParquet
,預設設定是true, 它代表使用spark-sql内置的parquet的reader和writer(即進行反序列化和序列化),它具有更好地性能,如果設定為false,則代表使用 Hive的序列化方式。
但是有時候當其設定為true時,會出現使用hive查詢表有資料,而使用spark查詢為空的情況.
但是,有些情況下在将
spark.sql.hive.convertMetastoreParquet
設為false,就會發生上面出現的異常。
這是因為在其為false時候,是使用hive-metastore使用的中繼資料進行讀取資料,而如果此表是使用spark sql DataSource建立的parquet表,其資料類型可能出現不一緻的情況,例如通過metaStore讀取到的是IntWritable類型,其建立了一個WritableIntObjectInspector用來解析資料,而實際上value是LongWritable類型,是以出現了類型轉換異常。
還有一個與該參數相關的參數是:
spark.sql.hive.convertMetastoreParquet.mergeSchema
, 如果也是true,那麼将會嘗試合并各個parquet 檔案的schema,以産生一個相容所有parquet檔案的schema。