Docker容器中PySpark无法写入文件的配置排查求助
问题描述
在Docker容器中运行PySpark、Hadoop及所有必要依赖组件,通过spark-submit查询Minio时读取文件操作正常,但将输出DataFrame写入文件时失败。容器内直接执行Python并在同路径创建文件可正常完成,怀疑缺失Spark配置。
报错信息
File "/usr/local/spark/python/lib/pyspark.zip/pyspark/sql/readwriter.py", line 1109, in save File "/usr/local/spark/python/lib/py4j-0.10.9-src.zip/py4j/java_gateway.py", line 1304, in __call__ File "/usr/local/spark/python/lib/pyspark.zip/pyspark/sql/utils.py", line 111, in deco File "/usr/local/spark/python/lib/py4j-0.10.9-src.zip/py4j/protocol.py", line 326, in get_return_value py4j.protocol.Py4JJavaError: An error occurred while calling o38.save : java.net.ConnectException: Call From 10d3463d04ce/10.0.1.132 to localhost:9000 failed on connection exception: java.net.ConnectException: Connection refused; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
相关代码
spark = SparkSession.builder.getOrCreate() spark_context = spark.sparkContext spark_context._jsc.hadoopConfiguration().set('fs.s3a.access.key', 'minio') spark_context._jsc.hadoopConfiguration().set( 'fs.s3a.secret.key', AWS_SECRET_ACCESS_KEY ) spark_context._jsc.hadoopConfiguration().set('fs.s3a.path.style.access', 'true') spark_context._jsc.hadoopConfiguration().set( 'fs.s3a.impl', 'org.apache.hadoop.fs.s3a.S3AFileSystem' ) spark_context._jsc.hadoopConfiguration().set('fs.s3a.endpoint', AWS_S3_ENDPOINT) spark_context._jsc.hadoopConfiguration().set( 'fs.s3a.connection.ssl.enabled', 'false' ) df = spark.sql(query) df.show() # 此操作完全正常 df.coalesce(1).write.format('json').save(output_path) # 此处报错
解决方案
从报错信息来看,核心问题是Spark写入时尝试连接localhost:9000但被拒绝,结合你的场景,可从以下几点排查解决:
修正Minio端点配置:
检查AWS_S3_ENDPOINT的值,在Docker容器中localhost指向容器自身,如果Minio部署在容器外部或其他Docker容器中,必须替换为Minio服务的实际可访问地址:- 若Minio在另一个Docker容器,使用容器名称(需在同一网络)或容器IP,例如
minio-container:9000 - 若Minio在主机上,使用主机的局域网IP,例如
192.168.1.100:9000
- 若Minio在另一个Docker容器,使用容器名称(需在同一网络)或容器IP,例如
提前在SparkSession构建阶段注入配置:
避免在SparkSession创建后再设置Hadoop配置,直接在构建时指定相关参数,确保读取和写入阶段都能生效:spark = SparkSession.builder \ .config("spark.hadoop.fs.s3a.access.key", "minio") \ .config("spark.hadoop.fs.s3a.secret.key", AWS_SECRET_ACCESS_KEY) \ .config("spark.hadoop.fs.s3a.path.style.access", "true") \ .config("spark.hadoop.fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem") \ .config("spark.hadoop.fs.s3a.endpoint", AWS_S3_ENDPOINT) \ .config("spark.hadoop.fs.s3a.connection.ssl.enabled", "false") \ .getOrCreate()验证容器到Minio的网络连通性:
在Docker容器内执行以下命令,确认能访问Minio服务:ping <minio-ip-or-hostname> telnet <minio-ip-or-hostname> 9000若无法连通,需检查Docker网络配置(如是否加入同一网桥)或Minio服务状态。
确认输出路径格式:
如果output_path是指向Minio的路径,确保格式为s3a://bucket-name/path/to/save;如果是本地路径,需检查Spark是否误将其解析为S3路径,可显式指定file://前缀(如file:///local/path)。
内容的提问来源于stack exchange,提问作者kichma
相关产品推荐
相关产品推荐

