SparkSQL與Hive metastore Parquet

大資料學習與分享發表於2020-11-03

Spark SQL為了更好的效能,在讀寫Hive metastore parquet格式的表時,會預設使用自己的Parquet SerDe,而不是採用Hive的SerDe進行序列化和反序列化。

該行為可以通過配置引數spark.sql.hive.convertMetastoreParquet進行控制,預設true。

這裡從表schema的處理角度而言,就必須注意Hive和Parquet相容性,主要有兩個區別:

  1. Hive是大小寫敏感的,但Parquet相反

  2. Hive會將所有列視為nullable,但是nullability在parquet裡有獨特的意義

由於上面的原因,在將Hive metastore parquet轉化為Spark SQL parquet時,需要相容處理一下Hive和Parquet的schema,即需要對二者的結構進行一致化。主要處理規則是:

  1. 有相同名字的欄位必須要有相同的資料型別,忽略nullability。相容處理的欄位應該保持Parquet側的資料型別,這樣就可以處理到nullability型別了(空值問題)

  2. 相容處理的schema應只包含在Hive後設資料裡的schema資訊,主要體現在以下兩個方面:

(1)只出現在Parquet schema的欄位會被忽略

(2)只出現在Hive後設資料裡的欄位將會被視為nullable,並處理到相容後的schema中

關於schema(或者說後設資料metastore),Spark SQL在處理Parquet表時,同樣為了更好的效能,會快取Parquet的後設資料資訊。此時,如果我們直接通過Hive或者其他工具對該Parquet表進行修改導致了後設資料的變化,那麼Spark SQL快取的後設資料並不能同步更新,此時需要手動重新整理Spark SQL快取的後設資料,來確保後設資料的一致性,方式如下:

// 第一種方式應用的比較多
1. sparkSession.catalog.refreshTable(s"${dbName.tableName}")
2. sparkSession.catalog.refreshByPath(s"${path}")

相關文章