使用 PySpark SQL 或 Hive "stored as Parquet"选项创建的表实际上并不以 Parquet 格式存储数据文件



我使用PySpark SQL:spark.sql("CREATE TABLE my_table (...) PARTITIONED BY (...) STORED AS Parquet")在Hadoop集群上创建表,并使用:spark.sql("INSERT INTO my_table SELECT * FROM my_other_table")加载一些数据,但是结果文件似乎不是Parquet文件,它们缺少".snappy.parquet"扩展。

在Hive中重复这些步骤时也会出现同样的问题。

但令人惊讶的是,当我使用PySpark DataFrame:df.write.partitionBy("my_column").saveAsTable(name="my_table", format="Parquet")创建表一切都很好。

所以,我的问题是:创建和填充拼花表的SQL方式有什么问题?Spark版本2.4.5,Hive版本3.1.2。

(2022年12月27日@mazaneicha回答后)不幸的是,在我正在使用的集群上没有拼花工具,所以我能做的最好的事情就是使用hdfs dfs -tail(和-head)检查文件的内容。在所有情况下都有"par1"在文件的开头和结尾。甚至更多——拼花版本的元数据(实现):

Method                      # of files      Total size  Parquet version                 File name
Hive Insert                 8               34.7 G      Jparquet-mr version 1.10.0      xxxxxx_x
PySpark SQL Insert          8               10.4 G      Iparquet-mr version 1.6.0       part-xxxxx-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.c000
PySpark DF insertInto       8               10.9 G      Iparquet-mr version 1.6.0       part-xxxxx-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.c000
PySpark DF saveAsTable      8               11.5 G      Jparquet-mr version 1.10.1      part-xxxxx-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-c000.snappy.parquet

(为了创建相同数量的文件,我使用了"重分区"带df,和"distribute by"使用SQL)。

所以,考虑到上面提到的,它仍然不清楚:

  1. 为什么4个案例中有3个没有文件扩展名?
  2. 为什么Hive创建的文件这么大?(没有压缩,我想)。
  3. 为什么PySpark SQL和PySpark Dataframe版本/parquet实现不同,如何显式设置它们?

文件格式不是由扩展名定义,而是由内容定义。您可以通过在文件的最开始和最后查找魔术字节PAR1来快速检查格式是否拼花。

对于深入的格式,元数据和一致性检查,尝试使用parquet-tools打开文件。

更新:正如在线文档中提到的,Spark通过它的公共数据源框架支持parquet作为众多数据源之一,因此它不必依赖Hive:

当从Hive metastore Parquet表中读取和写入到未分区的Hive metastore Parquet表时,Spark SQL将尝试使用自己的Parquet支持而不是Hive SerDe以获得更好的性能…

你可以在Spark git仓库中找到并查看这个实现(它是开源的!):))

最新更新