Amazon web services 通过Spark EMR读取嵌套目录中的S3文件

Amazon web services 通过Spark EMR读取嵌套目录中的S3文件,amazon-web-services,apache-spark,amazon-s3,pyspark,emr,Amazon Web Services,Apache Spark,Amazon S3,Pyspark,Emr,我想出了如何从S3目录将文件读入pyspark shell(和脚本),例如使用: rdd = sc.wholeTextFiles('s3n://bucketname/dir/*') 但是,虽然这让我可以读取一个目录中的所有文件,但我想读取所有目录中的每个文件 我不想将它们展平或立即加载所有内容,因为我会有内存问题 相反,我需要它以批处理的方式自动加载每个子目录中的所有文件。可能吗 以下是我的目录结构: S3_bucket_name->year(2016或2017)->month(最多12个文件

我想出了如何从S3目录将文件读入pyspark shell(和脚本),例如使用:

rdd = sc.wholeTextFiles('s3n://bucketname/dir/*')
但是,虽然这让我可以读取一个目录中的所有文件,但我想读取所有目录中的每个文件

我不想将它们展平或立即加载所有内容,因为我会有内存问题

相反,我需要它以批处理的方式自动加载每个子目录中的所有文件。可能吗

以下是我的目录结构:

S3_bucket_name->year(2016或2017)->month(最多12个文件夹)->day(最多31个文件夹)->sub-day文件夹(最多30个;基本上每天只对收集进行分区)

像这样的东西,除了会持续12个月,最多31天

BucketName
|
|
|---Year(2016)
|       |
|       |---Month(11)
|       |      |
|       |      |---Day(01)
|       |      |      |
|       |      |      |---Sub-folder(01)
|       |      |      |
|       |      |      |---Sub-folder(02)
|       |      |      |
|       |      |---Day(02)
|       |      |      |
|       |      |      |---Sub-folder(01)
|       |      |      |
|       |      |      |---Sub-folder(02)
|       |      |      |
|       |---Month(12)
|
|---Year(2017)
|       |
|       |---Month(1)
|       |      |
|       |      |---Day(01)
|       |      |      |
|       |      |      |---Sub-folder(01)
|       |      |      |
|       |      |      |---Sub-folder(02)
|       |      |      |
|       |      |---Day(02)
|       |      |      |
|       |      |      |---Sub-folder(01)
|       |      |      |
|       |      |      |---Sub-folder(02)
|       |      |      |
|       |---Month(2)
上面的每个箭头代表一个叉。e、 我已经收集了2年的数据,所以“年”叉有2年。每年最多12个月,每个月最多31个可能的日文件夹。每天都会有多达30个文件夹,因为我用这种方式将其拆分

我希望这是有道理的

我在看另一篇文章(),我相信他们建议使用通配符,比如:

rdd = sc.wholeTextFiles('s3n://bucketname/*/data/*/*') 
但问题是它试图在不同的子目录中找到一个公共文件夹——在这种情况下,没有保证,我只需要所有东西

然而,在这条推理路线上,我想如果我这样做了会怎么样

rdd = sc.wholeTextFiles("s3n://bucketname/*/*/*/*/*')
但问题是,现在我摆脱了记忆错误,可能是因为它一次加载所有东西,然后就崩溃了

理想情况下,我能做的是:

转到一天中的子目录级别,并阅读其中的内容,例如

先读2016/12/01,然后读2016/12/02,直到2012/12/31,然后读2017/01/01,然后读2017/01/02。。。2017/01/31等

这样,我就不用像上面那样使用五个通配符(*),而是知道如何在“day”级别查看每个子目录

我曾想过使用python字典来指定每天的文件路径,但这似乎是一种相当麻烦的方法。我的意思是:

file_dict = { 
    0:'2016/12/01/*/*', 
    1:'2016/12/02/*/*', 
    ...
    30:'2016/12/31/*/*',
}
{json object 1},
{json object 2},
{json object 3},
...
{json object n},
基本上是针对所有文件夹,然后使用如下方式迭代并加载它们:

sc.wholeTextFiles('s3n://bucketname/' + file_dict[i])
但我不想手动键入所有这些路径。我希望这是有意义的

编辑:

问这个问题的另一种方式是,如何以批处理的方式从嵌套的子目录结构中读取文件?如何在python中枚举s3存储桶中所有可能的文件夹名称?也许这会有帮助

编辑2:

我的每个文件中的数据结构如下所示:

file_dict = { 
    0:'2016/12/01/*/*', 
    1:'2016/12/02/*/*', 
    ...
    30:'2016/12/31/*/*',
}
{json object 1},
{json object 2},
{json object 3},
...
{json object n},
要使它成为“真正的json”,它要么像上面那样,结尾不带尾随逗号,要么像这样(请注意方括号,并且缺少最后的尾随逗号:

[
   {json object 1},
   {json object 2},
   {json object 3},
   ...
   {json object n}
 ]

我之所以完全在PySpark中使用它作为我提交的脚本,是因为我强迫自己手动处理这个格式问题。如果我使用Hive/Athena,我不知道如何处理它。

为什么不使用
Hive
,或者更好的是,
Athena
?它们都将在文件系统的顶部部署表,让您可以访问所有文件系统数据。然后你可以将其捕获到Spark中


或者,我相信您也可以使用Spark中的
HiveQL
来设置文件系统位置的
Attentiable
ontop,它会将所有内容注册为
Hive
表,您可以对其执行
SQL
。我已经有一段时间没有这样做了,但它肯定是可以做到的,我会研究一下。我没有当然,因为我不知道是否可以像HDFS一样将s3视为文件系统,但我猜使用Hive或Athena时,我应该仍然能够访问bucket中的所有内容…我会检查一下。感谢您的想法。s3事实上是作为HDFS直接暴露在EMR中的。它被称为EMRFS。运行hadoop命令时,您可以n do
hadoop fs-copyToLocal s3://bucket/file.txt./
例如(语法可能不太正确,已经有一段时间了)老实说,我的配置单元体验非常初级,但我不确定如何做到这一点,因为我的数据基本上是这样结构的:每个文件都有多个json对象(tweets)。但是每个json的格式都不完美,因为使用了多个json(以行分隔),你通常看不到结尾的逗号。只是一个换行符。但是在我看来,每个文件的结构都与我将添加到OP.updated OP的新编辑中的描述相同。我的数据结构可以让你明白我的意思。老实说,我不是一个JSON专家,无法为你提供一个关于这个的指针,但我相信谷歌会快速更新我的数据我会找到答案的。不过,配置单元中的分区肯定会解决您的问题:)如果您可以将JSON的东西放在它周围