spark支持用Parquet文件进行分区修剪吗

y1aodyip  于 2021-06-29  发布在  Hive
关注(0)|答案(3)|浏览(397)

我正在处理一个大数据集,它被两列分割- plant_name 以及 tag_id . 第二个分区- tag_id 有200000个唯一值,我主要通过特定的 tag_id 价值观。如果我使用以下spark命令:

sqlContext.setConf("spark.sql.hive.metastorePartitionPruning", "true")
sqlContext.setConf("spark.sql.parquet.filterPushdown", "true")
val df = sqlContext.sql("select * from tag_data where plant_name='PLANT01' and tag_id='1000'")

我希望能得到快速响应,因为它将解析为单个分区。在Hive和普雷斯托,这需要几秒钟,但在Spark运行数小时。
实际数据保存在一个s3 bucket中,当我提交sql查询时,spark关闭,首先从hive metastore获取所有分区(其中200000个),然后调用 refresh() 强制s3对象存储中所有这些文件的完整状态列表(实际调用 listLeafFilesInParallel ).
正是这两个操作非常昂贵,是否有任何设置可以让spark在调用元数据存储期间或之后立即修剪分区?

c9qzyr3d

c9qzyr3d1#

只是一个想法:
hadoopfsrelation的sparkapi文档说:(https://spark.apache.org/docs/1.6.2/api/java/org/apache/spark/sql/sources/hadoopfsrelation.html )
“…从存储在文件系统中的配置单元样式分区表读取数据时,它能够从输入目录的路径中发现分区信息,并在开始读取数据之前执行分区修剪…”
所以,我猜“listleaffilesinparallel”不会是个问题。
spark jira也有类似的问题:https://issues.apache.org/jira/browse/spark-10673
尽管“spark.sql.hive.verifypartitionpath”设置为false,但对性能没有影响,我怀疑问题可能是由未注册的分区引起的。请列出表中的分区,并验证是否所有分区都已注册。否则,恢复分区,如以下链接所示:
配置单元不读取spark生成的分区Parquet文件
更新:
我猜在写数据时设置了合适的Parquet块大小和页面大小。
用提到的分区创建一个新的配置单元表,文件格式为parquet,使用动态分区方法从非分区表加载https://cwiki.apache.org/confluence/display/hive/dynamicpartitions )运行普通配置单元查询,然后通过运行spark程序进行比较。
免责声明:我不是Spark/ParquetMaven。这个问题听起来很有意思,因此得到了回应。

bkkx9g8r

bkkx9g8r2#

是的,spark支持分区修剪。
spark提供分区目录列表(顺序或并行) listLeafFilesInParallel )第一次构建所有分区的缓存。同一应用程序中的查询,即扫描数据利用了此缓存。所以你看到的缓慢可能是因为这个缓存的建立。扫描数据的后续查询使用缓存来修剪分区。
这些日志显示了要填充缓存的分区。

App > 16/11/14 10:45:24 main INFO ParquetRelation: Listing s3://test-bucket/test_parquet_pruning/month=2015-01 on driver
App > 16/11/14 10:45:24 main INFO ParquetRelation: Listing s3://test-bucket/test_parquet_pruning/month=2015-02 on driver
App > 16/11/14 10:45:24 main INFO ParquetRelation: Listing s3://test-bucket/test_parquet_pruning/month=2015-03 on driver

这些日志显示修剪正在进行。

App > 16/11/10 12:29:16 main INFO DataSourceStrategy: Selected 1 partitions out of 20, pruned 95.0% partitions.

参考 convertToParquetRelation 以及 getHiveQlPartitionsHiveMetastoreCatalog.scala .

zvokhttg

zvokhttg3#

最近这里也出现了类似的问题:http://apache-spark-user-list.1001560.n3.nabble.com/spark-sql-reads-all-leaf-directories-on-a-partitioned-hive-table-td35997.html#a36007
这个问题很老了,但我想我也应该把答案贴在这里。

spark.sql.hive.convertMetastoreParquet=false

将使用HiveParquet镶嵌而不是Spark内置Parquet镶嵌。hive的parquet serde不会对所有分区执行listleaffiles操作,而是仅直接从所选分区读取文件。在有许多分区和文件的表上,这要快得多(也便宜得多)。你可以试试看!:)

相关问题