从S3加载spark DF,多个文件。以下哪种方法最好?

时间:2018-11-30 17:13:25

标签: amazon-s3 pyspark amazon-athena

我有一个s3存储桶,其中包含基于雅典娜的分区数据。使用雅典娜,我看到表中有1040亿行。这大约有2年的数据。 我们称之为big_table

分区是按天,按小时进行的,因此每天07-12-2018-00,01,02 ... 24。雅典娜字段为partition_datetime

在我的用例中,我只需要1个月的数据,大约4亿行。

因此出现了问题-直接从以下位置加载: 1.文件

spark.load(['s3://my_bucket/my_schema/my_table_directory/07-01-2018-00/file.snappy.parquet',\
         's3://my_bucket/my_schema/my_table_directory/07-01-2018-01/file.snappy.parquet' ],\
         .
         .
         .
         's3://my_bucket/my_schema/my_table_directory/07-31-2018-23/file.snappy.parquet'])

或2.通过pyspark使用SQL

df = spark.read.parquet('s3://my_bucket/my_schema/my_table_directory')
df = df.registerTempTable('tmp')
df = spark.sql("select * from my_schema.my_table_directory where partition_datetime >= '07-01-2018-00' and partition_datetime < '08-01-2018-00'")

我认为#1效率更高,因为我们只引入有关期间的数据。

2对我来说似乎效率很低,因为必须遍历整个1,040亿行(或更准确地说是partition_datetime字段)才能满足SELECT的要求。我被告知,由于延迟执行,这确实不是问题,并且所有1040亿行都没有df。我仍然说某些时候每个分区都必须由SELECT访问,因此选项1更有效。

我对此有其他意见。请鸣响

3 个答案:

答案 0 :(得分:0)

您所说的可能是正确的,但是它效率不高,因为它永远不会扩展。如果需要三个月的数据,则不能在load命令中指定90行代码。当涉及大数据时,这不是一个好主意。您始终可以通过使用独立的Spark或YARN集群对大型数据集执行操作。

答案 1 :(得分:0)

您可以在路径中使用通配符来仅加载给定范围内的文件。

spark.read.parquet('s3://my_bucket/my_schema/my_table_directory/07-{01,02,03}-2018-*/')

spark.read.parquet('s3://my_bucket/my_schema/my_table_directory/07-*-2018-*/')

答案 2 :(得分:-1)

汤姆,你是对的。 #1更有效率,而且更有效。但是,您可以创建要读取的文件列表的集合,然后要求spark仅读取那些文件。

blog可能对您的情况有所帮助。