10

我正在阅读镶木地板数据,我看到它列出了驱动程序端的所有目录

Listing s3://xxxx/defloc/warehouse/products_parquet_151/month=2016-01 on driver
Listing s3://xxxx/defloc/warehouse/products_parquet_151/month=2014-12 on driver

我在 where 子句中指定了 month=2014-12。我尝试过使用 spark sql 和数据框 API,看起来两者都没有修剪分区。

使用数据框 API

df.filter("month='2014-12'").show()

使用 Spark SQL

sqlContext.sql("select name, price from products_parquet_151 where month = '2014-12'")

我已经在 1.5.1、1.6.1 和 2.0.0 版本上尝试过上述方法

4

2 回答 2

3

Spark需要先在驱动中加载分区元数据,才能知道分区是否存在。Spark 将查询目录以查找现有分区,以了解在扫描数据期间是否可以修剪分区。

我已经在 Spark 2.0 上对此进行了测试,您可以在日志消息中看到。

16/10/14 17:23:37 TRACE ListingFileCatalog: Listing s3a://mybucket/reddit_year on driver
16/10/14 17:23:37 TRACE ListingFileCatalog: Listing s3a://mybucket/reddit_year/year=2007 on driver

这并不意味着我们正在扫描每个分区中的文件,但 Spark 将存储分区的位置以供将来在表上查询。

您可以看到它实际传递给分区过滤器以修剪数据的日志:

16/10/14 17:23:48 TRACE ListingFileCatalog: Partition spec: PartitionSpec(StructType(StructField(year,IntegerType,true)),ArrayBuffer(PartitionDirectory([2012],s3a://mybucket/reddit_year/year=2012), PartitionDirectory([2010],s3a://mybucket/reddit_year/year=2010), ...PartitionDirectory([2015],s3a://mybucket/reddit_year/year=2015), PartitionDirectory([2011],s3a://mybucket/reddit_year/year=2011)))
16/10/14 17:23:48 INFO ListingFileCatalog: Selected 1 partitions out of 9, pruned 88.88888888888889% partitions.

explain(True)如果您对查询 运行 an,您可以在逻辑计划中看到这一点:spark.sql("select created_utc, score, name from reddit where year = '2014'").explain(True)

这将向您显示计划,您可以看到它正在计划的底部进行过滤:

+- *BatchedScan parquet [created_utc#58,name#65,score#69L,year#74] Format: ParquetFormat, InputPaths: s3a://mybucket/reddit_year, PartitionFilters: [isnotnull(year#74), (cast(year#74 as double) = 2014.0)], PushedFilters: [], ReadSchema: struct<created_utc:string,name:string,score:bigint>
于 2016-10-14T18:25:31.687 回答
3

Spark 在通过 Hive 时有机会改进其分区修剪;见SPARK-17179

如果您只是直接访问对象存储,那么问题是针对对象存储的递归目录操作是真正的性能杀手。我和我的同事已经在HADOOP-11694的 S3A 客户端中完成了工作——现在需要跟进 Spark 的更改,以采用我们已经能够修复的特定 API 调用。为此,尽管我们需要确保我们正在使用具有真实布局的真实数据集,因此不要针对特定​​示例/基准进行优化。

目前,人们应该选择具有浅目录树的分区布局。

于 2016-10-20T14:40:37.540 回答