美文网首页
SparkSQL与Parquet兼容

SparkSQL与Parquet兼容

作者: liuzx32 | 来源:发表于2020-06-19 15:51 被阅读0次

Parquet是一种列式存储格式,很多种处理引擎都支持这种存储格式,也是sparksql的默认存储格式。Spark SQL支持灵活的读和写Parquet文件,并且对parquet文件的schema可以自动解析。当Spark SQL需要写成Parquet文件时,处于兼容的原因所有的列都被自动转化为了nullable。


分区发现

分区表时很多系统支持的,比如hive,对于一个分区表,往往是采用表中的某一或多个列去作为分区的依据,分区是以文件目录的形式体现。所有内置的文件源(Text/CSV/JSON/ORC/Parquet)都支持自动的发现和推测分区信息。例如,我们想取两个分区列,gender和country,先按照性别分区,再按照国家分区。

从spark 1.6开始,分区发现默认情况只会发现给定路径下的分区。比如,上面的分区表,假如你讲路径path/to/table/gender=male传递给SparkSession.read.parquet 或者 SparkSession.read.load 那么gender不会被认为是分区列。如果想检测到该分区,传给spark的路径应该是其父路径也即是path/to/table/,这样gender就会被认为是分区列。

Schema合并

跟protocol buffer,avro,thrift一样,parquet也支持schema演变升级。用户可以在刚开始的时候创建简单的schema,然后根据需要随时扩展新的列。

spark sql 用Parquet 数据源支持自动检测新增列并且会合并schema。

由于合并schema是一个相当耗费性能的操作,而且很多情况下都是不必要的,所以从spark 1.5开始就默认关闭掉该功能。有两种配置开启方式:

  1. 通过数据源option设置mergeSchema为true。

  2. 在全局sql配置中设置spark.sql.parquet.mergeSchema 为true.

Hive Metastore Parquet表转换

当读写hive metastore parquet格式表的时候,Spark SQL为了较好的性能会使用自己默认的parquet格式而不是采用hive SerDe。该行为是通过参数spark.sql.hive.convertMetastoreParquet空值,默认是true。

Hive和parquet兼容性

从表schema处理角度讲hive和parquet有两个主要的区别

  1. hive是大小写敏感的,但是parquet不是。

  2. hive会讲所有列视为nullable,但是nullability在parquet里有独特的意义。
    由于上面的原因,在将hive metastore parquet转化为spark parquet表的时候,需要处理兼容一下hive的schema和parquet的schema。

兼容处理的原则是:
  1. 有相同名字的字段必须要有相同的数据类型,忽略nullability。兼容处理的字段应该保持parquet侧的数据类型,这样就可以处理到nullability类型了。

  2. 兼容处理的schema应直接包含在hive元数据里的schema信息:
    a. 任何仅仅出现在parquet schema的字段将会被删除
    b. 任何仅仅出现在hive 元数据里的字段将会被视为nullable。

元数据刷新

Spark SQL为了更好的性能会缓存parquet的元数据。当spark 读取hive表的时候,schema一旦从hive转化为spark sql的,就会被spark sql缓存,如果此时表的schema被hive或者其他外部工具更新,必须要手动的去刷新元数据,才能保证元数据的一致性。

spark.catalog.refreshTable("my_table")

相关文章

网友评论

      本文标题:SparkSQL与Parquet兼容

      本文链接:https://www.haomeiwen.com/subject/bgavxktx.html