You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在YARN集群模式下通过spark-submit向Scala编写的Spark程序传递本地文件路径

解决YARN Cluster模式下Spark读取本地文件失败的问题

我来帮你分析问题根源,再给出针对性的解决方案:

问题核心原因

你遇到的问题本质是YARN Cluster模式的运行机制差异:当使用--deploy-mode cluster提交任务时,Spark Driver会运行在YARN集群的某个Worker节点上,而不是你执行spark2-submit命令的本地Linux服务器。

  • 第一次尝试用--files ${csv_file}时,Cluster模式下Spark默认会把路径解析为HDFS路径,所以它去HDFS根目录查找文件,自然找不到本地机器上的文件。
  • 第二次传命令行参数的方式,虽然代码能拿到路径,但Driver所在的集群节点上并没有/usr/usr1/Test.csv(这个文件只存在于你提交命令的本地机器),因此依然报错。

可行解决方案

根据你的需求,有两种常用的解决方式,可根据场景选择:

方案1:将文件上传到HDFS(推荐)

这是最稳妥的方案,尤其适合大文件或需要重复使用的场景:

  1. 先把本地文件上传到HDFS:
    hdfs dfs -put /usr/usr1/Test.csv /user/your-username/Test.csv
    
  2. 修改提交命令,传入HDFS路径作为参数:
    csv_file="hdfs:///user/your-username/Test.csv" 
    spark2-submit \ 
    --num-executors 30 \ 
    --driver-memory 12g \ 
    --executor-memory 14g \ 
    --executor-cores 4 \ 
    --class driver_class \ 
    --name TTTTTT \ 
    --master yarn \ 
    --deploy-mode cluster \ 
    --files myprop.properties \ 
    abc.jar ${csv_file}
    
  3. 代码无需额外修改,保持用args(0)获取路径即可——HDFS路径在整个集群都能正常访问。

方案2:利用Spark分布式缓存(--files参数)

如果你的文件很小,或者不想上传到HDFS,可以用--files将本地文件分发到所有Driver和Executor节点的分布式缓存中:

  1. 修改代码,通过SparkFiles.get()获取缓存后的文件路径:
    import org.apache.spark.SparkFiles
    
    def main(args: Array[String]) { 
      val spark = SparkSession.builder.appName("SparkData").getOrCreate() 
      val sc = spark.sparkContext 
      sc.setLogLevel("ERROR") 
      import spark.implicits._ 
      
      // 从分布式缓存中获取文件,参数是文件名而非原本地路径
      val filepath = SparkFiles.get("Test.csv")
      
      val df = spark.read.format("csv").load(filepath)
      df.show() 
      spark.stop() 
    }
    
  2. 修改提交命令,将本地文件路径加入--files参数:
    spark2-submit \ 
    --num-executors 30 \ 
    --driver-memory 12g \ 
    --executor-memory 14g \ 
    --executor-cores 4 \ 
    --class driver_class \ 
    --name TTTTTT \ 
    --master yarn \ 
    --deploy-mode cluster \ 
    --files myprop.properties,/usr/usr1/Test.csv \ 
    abc.jar
    
    这里不需要传命令行参数,Spark会自动把/usr/usr1/Test.csv复制到每个节点的临时目录,你只需要用文件名Test.csv通过SparkFiles.get()获取实际路径即可。

注意事项

  • 如果文件体积较大,不推荐方案2,因为--files会把文件复制到每个集群节点,占用额外存储资源,此时方案1(HDFS)更高效。
  • 永远记住:Cluster模式下Driver不在本地机器,任何本地路径的引用都要确保集群节点能访问到——要么通过分布式缓存分发,要么使用共享存储(如HDFS)。

内容的提问来源于stack exchange,提问作者VnS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 16:33:12