Spark 将输出写回输入目录

Spark writing output back to the input directory

最近遇到一个场景,需要从目录中读取HDFS的输入

 /user/project/jsonFile

并将结果写回同一目录:

 /user/project/jsonFile

读取 jsonFile 后执行多个连接并将结果写入 /user/project/jsonFile 使用:

result.write().mode(SaveMode.Overwrite).json("/user/project/jsonFile");

下面是我看到的错误:

[task-result-getter-0]o.a.s.s.TaskSetManager: Lost task 10.0 in stage 7.0 (TID 2508, hddev1db015dxc1.dev.oclc.org, executor 3): java.io.FileNotFoundException: File does not exist: /user/project/jsonFile
    at org.apache.hadoop.hdfs.server.namenode.INodeFile.valueOf(INodeFile.java:87)
    at org.apache.hadoop.hdfs.server.namenode.INodeFile.valueOf(INodeFile.java:77)
    
It is possible the underlying files have been updated. You can explicitly invalidate the cache in Spark by running 'REFRESH TABLE tableName' command in SQL or by recreating the Dataset/DataFrame involved.
    at org.apache.spark.sql.execution.datasources.FileScanRDD$$anon.org$apache$spark$sql$execution$datasources$FileScanRDD$$anon$$readCurrentFile(FileScanRDD.scala:127)
    at org.apache.spark.sql.execution.datasources.FileScanRDD$$anon.nextIterator(FileScanRDD.scala:177)

为什么会抛出 java.io.FileNotFoundException: File does not exist? result 是包含写入回 HDFS 的连接输出的数据集,一旦 result 数据集可用,spark 就不能写入在同一输入目录中将数据返回到 HDFS?

这让我觉得一些执行者完成了对输入的连接,他们准备将结果写回 HDFS,而一些执行者仍在从同一个 HDFS 目录读取数据的过程中,现在正在被覆盖导致 FileNotFound。是真的吗?

感谢您的帮助

您在从同一目录读取和写入时正在使用覆盖。一种方法是使用 Append 而不是 Overwrite

result.write().mode(SaveMode.Append).json("/user/project/jsonFile");

另一种解决方法是将您的数据存储在另一个文件夹中,然后将其作为源读取到您的初始位置。

read from source
make your data transformations
write transformed data into tempLocation
read from tempLocation
write into source