通过 pyspark 加载文件名中包含冒号的 Amazon S3 文件

Posted

技术标签:

【中文标题】通过 pyspark 加载文件名中包含冒号的 Amazon S3 文件【英文标题】:Load a Amazon S3 file which has colons within the filename through pyspark 【发布时间】:2015-12-04 16:36:33 【问题描述】:

我有一个 S3 存储桶,其中包含多个文件名中带有冒号的文件。

例子:

s3://my_bucket/my_data/en/2015120/batch:222:111:00000.jl.gz

我正在尝试将其加载到 spark RDD 中并按如下方式访问第一行。

my_data = sc.textFile("s3://my_bucket/my_data/en/2015120/batch:222:111:00000.jl.gz")
my_data.take(1)

但这会引发,

llegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: 

任何建议单独加载这些文件,或者最好作为整个文件夹加载

【问题讨论】:

你可以试试在文件名中使用*。像 's3://path/*.gz' 。我正在使用与您上面相同的东西,它对我有用。 【参考方案1】:

我通过将冒号替换为 url 编码格式来实现它。

: 将替换为 %3A

要仔细检查,请单击 S3 中的一个对象并查看“链接”

【讨论】:

【参考方案2】:

对此的一种解决方案是使用自定义 FileSystem 实现,就像他们所做的 here (Totango Labs)

它的要点是您绕过了内部globStatus 函数,该函数试图将文件名解释为路径,而不是使用listStatus。缺点是虽然这将允许您使用带有冒号的 S3 URL,但它不允许您在 URL 中指定通配符。

final Configuration hadoopConf = sparkContext.hadoopConfiguration();
hadoopConf.set("fs." + CustomS3FileSystem.SCHEMA + ".impl",
  CustomS3FileSystem.class.getName());

public class CustomS3FileSystem extends NativeS3FileSystem 
  public static final String SCHEMA = "custom";

  @Override
  public FileStatus[] globStatus(final Path pathPattern, final PathFilter filter)
      throws IOException 
    final FileStatus[] statusList = super.listStatus(pathPattern);
    final List<FileStatus> result = Lists.newLinkedList();
    for (FileStatus fileStatus : statusList) 
      if (filter.accept(fileStatus.getPath())) 
        result.add(fileStatus);
      
    
    return result.toArray(new FileStatus[] );
  

【讨论】:

【参考方案3】:

请注意,为了访问 S3,您需要使用 s3n 架构,而不仅仅是 s3,如 Spark FAQ 中所述,否则 Hadoop 解析器 fails。

【讨论】:

以上是关于通过 pyspark 加载文件名中包含冒号的 Amazon S3 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何将存储在 HDFS 中包含行的文本文件转换为 Pyspark 中的数据框?

如果 csv 文件中包含 Pyspark 中的特定关键字,则跳过该行

加入两个数据框和结果数据框在 PySpark 中包含不重复的项目?

删除R中包含冒号的字符串

如何使用 xpath 检索属性名称中包含冒号的属性的值

PySpark Dataframe Aggregation 中包含 null 的计数