在Docker中运行Spark时如何访问本地机器文件?
解决Docker Spark集群读取本地文件失败的问题
问题根源
当你使用spark://localhost:7077集群模式运行Spark时,读文件的任务会被分发到spark-worker容器执行。但worker容器的文件系统和宿主机完全隔离,宿主机本地的/Users/UserName/Projects/spark/test/data/路径在容器内并不存在,因此抛出FileNotFoundException。而本地PySpark能正常运行是因为用了local模式,任务直接在宿主机执行,可直接访问本地文件。
解决方案
方案一:同步挂载数据卷到所有集群节点(推荐用于测试/开发)
修改docker-compose.yml,将宿主机的data目录挂载到master和所有worker容器的相同绝对路径下,确保所有集群节点都能访问到文件:
version: '2' services: spark: image: docker.io/bitnami/spark:3.3 environment: - SPARK_MODE=master - SPARK_RPC_AUTHENTICATION_ENABLED=no - SPARK_RPC_ENCRYPTION_ENABLED=no - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no - SPARK_SSL_ENABLED=no ports: - '8080:8080' - '7077:7077' volumes: # 宿主机本地data目录 → 容器内统一路径 - /Users/UserName/Projects/spark/test/data:/opt/spark/data spark-worker: image: docker.io/bitnami/spark:3.3 environment: - SPARK_MODE=worker - SPARK_MASTER_URL=spark://spark:7077 - SPARK_WORKER_MEMORY=1G - SPARK_WORKER_CORES=1 - SPARK_RPC_AUTHENTICATION_ENABLED=no - SPARK_RPC_ENCRYPTION_ENABLED=no - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no - SPARK_SSL_ENABLED=no volumes: # 与master保持相同的挂载路径 - /Users/UserName/Projects/spark/test/data:/opt/spark/data
然后修改PySpark脚本的文件路径为容器内的绝对路径:
employees = spark.read.csv('/opt/spark/data/employees.csv', header=True) salaries = spark.read.csv('/opt/spark/data/salaries.csv', header=True)
注意:确保宿主机的data目录权限正确,容器拥有读取该目录的权限;如果使用相对路径挂载(如./data:/opt/spark/data),需保证docker-compose up是在宿主机data目录的上级目录执行。
方案二:切换到Local模式(仅用于小数据量测试)
如果只是本地测试,不需要集群资源,可以将SparkSession改为local模式,任务直接在宿主机执行:
spark = SparkSession.builder.master("local[*]").appName("test").getOrCreate()
这种方式不需要修改Docker配置,直接用本地文件路径即可读取。
方案三:使用分布式存储(生产环境推荐)
生产环境中,建议将文件上传到HDFS、S3等分布式存储系统,Spark从分布式路径读取文件,避免依赖本地文件系统:
employees = spark.read.csv('hdfs://namenode:9000/dataset/employees.csv', header=True)
内容的提问来源于stack exchange,提问作者Kilipukki
相关产品推荐
相关产品推荐

