代码之家  ›  专栏  ›  技术社区  ›  tooptoop4

s3afilesystem-当前缀是文件和目录树的一部分时,filealreadyexistsexception

  •  0
  • tooptoop4  · 技术社区  · 6 年前

    我们使用aws-java-sdk-1.7.4.jar hadoop-aws-2.7.5.jar运行apache spark作业,将拼花文件写入s3桶。

    我们在s3中有“s3://mybucket/d1/d2/d3/d4/d5/d6/d7”键(d7是一个文本文件)。我们还提供了“s3://mybucket/d1/d2/d3/d4/d5/d6/d7/d8/d9/part_dt=20180615/a.parquet”(a.parquet是一个文件)

    当我们运行spark作业在“s3://mybucket/d1/d2/d3/d4/d5/d6/d7/d8/d9/part嫘dt=20180616/”下编写b.parquet文件时(即希望在s3中创建“s3://mybucket/d1/d2/d3/d4/d5/d6/d7/d8/d9/part嫘dt=20180616/b.parquet”),我们得到以下错误

    org.apache.hadoop.fs.FileAlreadyExistsException: Can't make directory for path 's3a://mybucket/d1/d2/d3/d4/d5/d6/d7' since it is a file.
    at org.apache.hadoop.fs.s3a.S3AFileSystem.mkdirs(S3AFileSystem.java:861)
    at org.apache.hadoop.fs.FileSystem.mkdirs(FileSystem.java:1881)
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   stevel    6 年前

    如中所述 HADOOP-15542 . 在“普通”fs的目录下不能有文件;在s3a连接器中不能得到它们,至少在它做了足够的尽职调查的地方。

    它只是混淆了每一个树遍历算法,重命名,删除,任何扫描文件。这将包括spark分区逻辑。您试图创建的新目录树可能对调用方不可见。(您可以通过创建它、将文本文件放置到位来测试它,看看会发生什么)

    我们试图定义一个fs应该在 The Hadoop Filesystem Specification ,包括定义“非常明显”的东西,以至于没有人费心写下它们或为之编写测试,例如

    • 只有目录可以有子目录
    • 所有的孩子都必须有父母
    • 只有文件可以有数据(异常:reiserfs)
    • 文件的长度和它们所说的一样长(这就是为什么S3A不支持客户端加密,BTW)。

    我们经常会发现一些我们忘记考虑的新东西,哪些“真正的”文件系统强制执行了开箱即用,但哪些对象存储没有。然后我们添加测试,尽力维护这个隐喻,除非性能影响会使其不可用。然后我们选择不去修理,希望没人注意到。一般来说,由于在hadoop/hive/spark空间中处理数据的人对文件系统的功能有着相同的先入之见,因此这些模糊性实际上不会在生产中造成问题。

    当然,除了最终的一致性,这就是为什么不应该在没有一致性服务(s3guard,consistent emrfs)或为这个世界设计的提交协议(s3 a committer,databricks dbio)的情况下直接从spark向s3写入数据。