我们使用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是文本文件)。我们还有按键's://mybucket/d1/d2/d3/d4/d5/d6/d7/d8/d9/part_dt=20180615/a.parquet'(a.parquet is a file)
当我们运行一个spark作业来写's3:// mybucket / d1 / d2 / d3 / d4 / d5 / d6 / d7 / d8 / d9 / part_dt = 20180616 /'时的b.parquet文件(即想有's3://mybucket/d1/d2/d3/d4/d5/d6/d7/d8/d9/part_dt=20180616/b.parquet'在s3中创建)我们得到以下错误
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)
答案 0 :(得分:0)
如HADOOP-15542中所述。你不能在“普通”FS的目录下拥有文件;你没有把它们放在S3A连接器中,至少在它做了足够的尽职调查的时候。
它只会混淆每一个树行走算法,重命名,删除,扫描文件的任何内容。这将包括spark分区逻辑。您尝试创建的新目录树可能对调用者不可见。 (你可以通过创建它来测试它,将该文本文件的PUT放到位,看看会发生什么)
我们尝试定义FS应该在The Hadoop Filesystem Specification中做什么,包括定义“如此明显”的东西,没有人费心写下来或编写测试,例如
我们经常发现一些我们忘记考虑的新事物,哪些“真正的”文件系统强制执行,但哪些对象存储不执行。然后我们添加测试,尽量保持比喻,除非性能影响使其无法使用。然后我们选择不修理东西,希望没有人注意到。通常,因为在hadoop / hive / spark空间中处理数据的人对文件系统的作用有着相同的先入之见,所以这些含糊不一致实际上不会导致生产中出现问题。
除了最终的一致性之外,这就是为什么你不应该在没有一致性服务(S3Guard,一致的EMRFS)或为这个世界设计的提交协议的情况下从spark直接写入数据的原因(S3A Committer,databricks DBIO)