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

本地Spark应用连接Docker中HDFS集群写入文件失败求助

问题分析与解决方案

核心问题

本地Spark客户端无法连接Docker容器内DataNode的数据传输端口(9866):

  • NameNode返回给Spark的是DataNode在Docker内部网络的IP(172.18.0.3)和未映射的9866端口
  • 宿主机无法直接访问Docker容器的内部IP与未暴露端口,导致连接超时、文件写入失败

解决方案

方案1:端口映射+HDFS配置修正(生产/开发通用)

  1. 更新Docker Compose配置
    给DataNode添加9866端口映射,并配置对外暴露的地址:

    version: "3.9"
    
    networks:
      hadoop-net:
        driver: bridge
    
    services:
      hdfs-namenode:
        container_name: "hdfs-namenode"
        image: "apache/hadoop:3"
        hostname: "hdfs-namenode"
        command: ["hdfs", "namenode"]
        ports:
          - "8020:8020"
          - "9870:9870"
        env_file:
          - ./hadoop-config/config.env
        environment:
          ENSURE_NAMENODE_DIR: "/tmp/hadoop-root/dfs/name"
        networks:
          - hadoop-net
    
      hdfs-datanode:
        depends_on:
          hdfs-namenode:
            condition: service_started
        container_name: "hdfs-datanode"
        image: "apache/hadoop:3"
        hostname: "hdfs-datanode"
        command: ["hdfs", "datanode"]
        ports:
          - "9864:9864"
          - "9866:9866"  # 新增数据传输端口映射
        env_file:
          - ./hadoop-config/config.env
        environment:
          # 配置DataNode对外暴露的地址与端口
          HDFS_DATANODE_ADDRESS: 0.0.0.0:9866
          HDFS_DATANODE_IPC_ADDRESS: 0.0.0.0:9867
          HDFS_DATANODE_HTTP_ADDRESS: 0.0.0.0:9864
        networks:
          - hadoop-net
    
  2. 配置HDFS全局参数
    在./hadoop-config/config.env文件中添加以下内容(无文件则新建):

    CORE_CONF_fs_defaultFS=hdfs://hdfs-namenode:8020
    # 关闭DataNode注册时的IP/主机名检查
    HDFS_CONF_dfs_namenode_datanode_registration_ip___hostname___check=false
    # 让客户端使用DataNode的主机名而非IP访问
    HDFS_CONF_dfs_client_use_datanode_hostname=true
    HDFS_CONF_dfs_datanode_use_datanode_hostname=true
    
  3. 重启集群

    docker-compose down -v
    docker-compose up -d
    

方案2:让Spark接入Docker网络(开发测试快速解决)

直接让Spark客户端加入Docker的hadoop-net网络,绕过宿主机与容器的网络隔离:

  1. 获取Docker网络名称:
    docker network ls | grep hadoop-net
    
  2. 在Docker网络内运行Spark:
    docker run --network big-data-project-2_hadoop-net -it --rm apache/spark:3.5.1 spark-shell \
      --conf spark.hadoop.fs.defaultFS=hdfs://hdfs-namenode:8020
    
    在该Shell环境中执行你的Spark代码即可。

方案3:Spark客户端配置代理访问(临时测试用,性能差)

通过强制Spark使用NameNode代理读写数据,避免直接连接DataNode:

spark = SparkSession.builder \
    .config("spark.hadoop.fs.defaultFS", "hdfs://localhost:8020") \
    .config("spark.hadoop.dfs.client.use.datanode.hostname", "false") \
    .config("spark.hadoop.dfs.client.block.write.replace-datanode-on-failure.policy", "NEVER") \
    .appName("Spark SQL") \
    .getOrCreate()

验证方法

重启集群后,执行Spark代码,再通过以下命令检查文件内容:

docker exec -it hdfs-namenode hdfs dfs -cat /user/hadoop/data/people.csv/*

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:14:51