Spark RDD 方法 "saveAsTextFile" 即使在删除输出目录后也会抛出异常。 org.apache.hadoop.mapred.FileAlreadyExistsException

Spark RDD method "saveAsTextFile" throwing exception Even after deleting the output directory. org.apache.hadoop.mapred.FileAlreadyExistsException

我在参数中包含目标的 RDD[String] 上调用此方法。 (斯卡拉)

即使在启动前删除了目录,该过程仍会出现此错误。 我在 EMR 集群上 运行 这个过程,输出位置在 aws S3。 下面是使用的命令:

spark-submit --deploy-mode cluster --class com.hotwire.hda.spark.prd.pricingengine.PRDPricingEngine --conf spark.yarn.submit.waitAppCompletion=true --num-executors 21 --executor-cores 4 --executor-memory 20g --driver-memory 8g --driver-cores 4 s3://bi-aws-users/sbatheja/hotel-shopper-0.0.1-SNAPSHOT-jar-with-dependencies.jar -d 3 -p 100 --search-bucket s3a://hda-prod-business.hotwire.hotel.search --prd-output-path s3a://bi-aws-users/sbatheja/PRD/PriceEngineOutput/

日志:

16/07/07 11:27:47 INFO BlockManagerMaster: BlockManagerMaster stopped
16/07/07 11:27:47 INFO OutputCommitCoordinator$OutputCommitCoordinatorEndpoint: OutputCommitCoordinator stopped!
16/07/07 11:27:47 INFO SparkContext: Successfully stopped SparkContext
16/07/07 11:27:47 INFO ApplicationMaster: Unregistering ApplicationMaster with FAILED (diag message: User class threw exception: **org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory s3a://bi-aws-users/sbatheja/PRD/PriceEngineOutput already exists)**
16/07/07 11:27:47 INFO RemoteActorRefProvider$RemotingTerminator: Shutting down remote daemon.
16/07/07 11:27:47 INFO RemoteActorRefProvider$RemotingTerminator: Remote daemon shut down; proceeding with flushing remote transports.
16/07/07 11:27:47 INFO AMRMClientImpl: Waiting for application to be successfully unregistered.
16/07/07 11:27:47 INFO RemoteActorRefProvider$RemotingTerminator: Remoting shut down.
16/07/07 11:27:47 INFO ApplicationMaster: Deleting staging directory .sparkStaging/application_1467889642439_0001
16/07/07 11:27:47 INFO ShutdownHookManager: Shutdown hook called
16/07/07 11:27:47 INFO ShutdownHookManager: Deleting directory /mnt/yarn/usercache/hadoop/appcache/application_1467889642439_0001/spark-7f836950-a040-4216-9308-2bb4565c5649

它在该位置创建“_temporary”目录,其中包含空零件文件。

总之一句话:
确保spark-corescala-library的scala版本一致


我遇到了同样的问题。 当我将文件保存到 HDFS 时,它抛出一个异常:org.apache.hadoop.mapred.FileAlreadyExistsException
然后查看HDFS文件目录,有一个空的临时文件夹:TARGET_DIR/_temporary/0

可以提交作业,打开详细配置:./spark-submit --verbose。 再看完整的上下文和日志,肯定是其他错误导致的。 我的作业在RUNNING状态,抛出第一个错误:

17/04/23 11:47:02 ERROR executor.Executor: Exception in task 1.0 in stage 0.0 (TID 1)
java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)[Ljava/lang/Object;

然后作业将重试并重新执行。这时,job重新执行,会发现刚才的目录已经创建好了。并且还会抛出目录已经存在。

经过确认第一个错误是版本兼容性问题。 spark版本为2.1.0,对应的spark-corescala版本为2.11,scala版本的scala-library依赖为2.12.xx.

当两个scala版本修改一致时(一般修改scala-library版本),可以解决第一个异常问题,然后job就可以正常了FINISHED.
pom.xml 示例:

<!-- Spark -->
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.11</artifactId>
    <version>2.1.0</version>
</dependency>
<!-- scala -->
<dependency>
    <groupId>org.scala-lang</groupId>
    <artifactId>scala-library</artifactId>
    <version>2.11.7</version>
</dependency>