本地Docker Spark集群PySpark连接报错、作业超时问题排查
问题根因
- Worker节点Master地址配置错误:docker-compose中所有Worker的
SPARK_MASTER_URL填写为spark://spark:7077,但配置中不存在名为spark的服务,仅定义了spark-master服务,导致Worker启动后无法注册到Master,集群本身处于异常状态。 - 双向网络通信不通:Spark执行作业时,不仅本地启动的Driver进程需要连接Master的7077端口,Master、Worker节点还需要反向连接Driver进程,同时Worker与Driver、Worker之间需要通过块传输端口交换数据。当前配置仅映射了Master的7077、8080端口,既未暴露Worker的通信端口,也未配置Driver的宿主机可访问参数,导致集群节点无法连通本地Driver,触发BlockManager注册空指针、作业超时问题。
- 缺少Master绑定配置:Bitnami提供的Spark镜像默认不会将Master服务绑定到所有网卡,未手动配置时会出现容器外客户端连接异常。
修复步骤
1. 修正docker-compose配置
替换原有配置为以下内容,核心修改点包括:新增自定义集群网络、修正Worker的Master连接地址、添加Master主机绑定配置、映射Worker通信端口段避免随机端口不可达:
services: spark-master: image: docker.io/bitnami/spark:3.2.1 environment: - SPARK_MODE=master - SPARK_MASTER_HOST=spark-master - SPARK_RPC_AUTHENTICATION_ENABLED=no - SPARK_RPC_ENCRYPTION_ENABLED=no - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no - SPARK_SSL_ENABLED=no ports: - '7075:8080' - "7077:7077" volumes: - "./execution_scripts:/execution_scripts:rw" networks: - spark-net spark-worker: image: docker.io/bitnami/spark:3.2.1 environment: - SPARK_MODE=worker - SPARK_MASTER_URL=spark://spark-master:7077 - SPARK_WORKER_MEMORY=2G - SPARK_WORKER_CORES=1 - SPARK_RPC_AUTHENTICATION_ENABLED=no - SPARK_RPC_ENCRYPTION_ENABLED=no - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no - SPARK_SSL_ENABLED=no ports: - "8081:8081" - "30000-30010:30000-30010" networks: - spark-net spark-worker-2: image: docker.io/bitnami/spark:3.2.1 environment: - SPARK_MODE=worker - SPARK_MASTER_URL=spark://spark-master:7077 - SPARK_WORKER_MEMORY=2G - SPARK_WORKER_CORES=1 - SPARK_RPC_AUTHENTICATION_ENABLED=no - SPARK_RPC_ENCRYPTION_ENABLED=no - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no - SPARK_SSL_ENABLED=no ports: - "8082:8081" - "30011-30020:30000-30010" networks: - spark-net spark-worker-3: image: docker.io/bitnami/spark:3.2.1 environment: - SPARK_MODE=worker - SPARK_MASTER_URL=spark://spark-master:7077 - SPARK_WORKER_MEMORY=2G - SPARK_WORKER_CORES=1 - SPARK_RPC_AUTHENTICATION_ENABLED=no - SPARK_RPC_ENCRYPTION_ENABLED=no - SPARK_LOCAL_STORAGE_ENCRYPTION_ENABLED=no - SPARK_SSL_ENABLED=no ports: - "8083:8081" - "30021-30030:30000-30010" networks: - spark-net networks: spark-net: driver: bridge
配置修改完成后,先执行docker-compose down -v清理旧的异常容器,再执行docker-compose up -d启动集群。启动后访问http://localhost:7075查看Master WebUI,确认3个Worker均已成功注册,状态为ALIVE。
2. 修正PySpark连接代码
在SparkSession配置中添加Driver地址、端口绑定参数,保证容器内节点可以反向连通本地Driver,修改后代码如下:
import findspark findspark.init() from pyspark.sql import SparkSession spark = SparkSession.builder\ .appName("Day1_1")\ .master("spark://localhost:7077")\ .config("spark.driver.host", "127.0.0.1")\ .config("spark.driver.bindAddress", "0.0.0.0")\ .config("spark.driver.port", "30000")\ .config("spark.blockManager.port", "30001")\ .config("spark.port.maxRetries", "10")\ .getOrCreate() # 连通性测试可先执行下面的代码,不用直接读文件 # spark.range(100).count() df_NYTaxi = spark.read.csv(file)
注意:如果读取的是本地宿主机上的CSV文件,需要将文件所在目录挂载到所有Master、Worker容器的相同绝对路径下,否则Worker会抛出文件不存在异常。
3. 异常排查补充
- 启动集群前确认本地7077、30000-30030端口未被其他进程占用
- 本地PySpark版本需与镜像内Spark版本完全一致,当前均为3.2.1符合要求
- 若仍出现连接超时,可临时关闭本地防火墙测试,确认不是防火墙拦截了宿主机与容器间的通信
内容的提问来源于stack exchange,提问作者TheDataJanit0r
相关产品推荐
相关产品推荐

