Spark读取HDFS目录后覆写同目录报FileNotFoundException原因问询
问题原因解答
核心错误原因
你的猜测完全正确,该报错由Spark执行机制+同路径读写+覆写模式共同触发,具体逻辑如下:
- Spark的所有转换算子(join、filter、map等)均为懒执行,你代码中构造的
result数据集只是保存了「从/user/project/jsonFile读取数据、执行多次join」的逻辑链路,并没有真正触发计算、也没有将计算结果提前落盘/存入内存。 result.write()是action算子,只有调用到这一步时Spark才会真正执行整个计算链路。而SaveMode.Overwrite的默认执行顺序是:先清空目标路径的所有内容,再执行前面的读源数据、join等计算逻辑。此时源数据所在的路径已经被提前清空,后续计算读取源文件时自然会抛出文件不存在的错误。- 即使不考虑Overwrite提前删路径的逻辑,也会出现你猜测的并行任务冲突问题:Spark的任务是多节点并行执行的,部分先完成计算的task开始写入并删除原路径文件时,还未完成读源数据步骤的task就会找不到对应文件。
可行解决方案
- 优先采用临时目录中转方案:先将
result写入一个新的临时HDFS路径,确认计算完全成功后,再用HDFS命令将临时路径的内容移动到目标路径,最后删除临时路径即可。该方案不会有丢失源数据的风险,是生产环境的通用方案。 - 如果数据量较小,可以提前触发计算缓存结果:调用
result.persist(StorageLevel.MEMORY_AND_DISK_SER)或者result.count(),确保所有源数据已经读取完成、计算结果已经生成后,再执行写入逻辑,此时覆写目标路径不会影响已经完成的计算。 - 如果是操作Spark SQL外部表,可以按照报错提示先执行
REFRESH TABLE 表名刷新元数据,但该方案不适用于你当前直接读写路径的场景。
内容的提问来源于stack exchange,提问作者Neethu Lalitha
相关产品推荐
相关产品推荐

