docker - 如何使 HDFS 在 docker swarm 中工作

标签 docker hadoop hdfs docker-swarm

我无法在 docker swarm 中使我的 HDFS 设置工作。
为了理解这个问题,我将我的设置减少到最低限度:

  • 1台物理机
  • 1 个名称节点
  • 1 个数据节点

  • 此设置在 docker-compose 中运行良好,但在 docker-swarm 中失败,使用相同的 compose 文件。

    这是撰写文件:
    version: '3'
    services:
      namenode:
          image: uhopper/hadoop-namenode
          hostname: namenode
          ports:
            - "50070:50070"
            - "8020:8020"
          volumes:
            - /userdata/namenode:/hadoop/dfs/name
          environment:
            - CLUSTER_NAME=hadoop-cluster
    
      datanode:
        image: uhopper/hadoop-datanode
        depends_on:
          - namenode
        volumes:
          - /userdata/datanode:/hadoop/dfs/data
        environment:
          - CORE_CONF_fs_defaultFS=hdfs://namenode:8020
    

    为了测试它,我在我的主机(物理)机器上安装了一个 hadoop 客户端,在 core-site.xml 中只有这个简单的配置:
    <configuration>
      <property><name>fs.defaultFS</name><value>hdfs://0.0.0.0:8020</value></property>
    </configuration>
    

    然后我运行以下命令:
    hdfs dfs -put test.txt /test.txt
    

    使用 docker-compose(只是运行 docker-compose up)它可以工作并且文件是用 HDFS 编写的。

    使用 docker-swarm,我正在运行:
    docker swarm init 
    docker stack deploy --compose-file docker-compose.yml hadoop
    

    然后当所有服务都启动时,我将我的文件放在 HDFS 上,它会像这样失败:
    INFO hdfs.DataStreamer: Exception in createBlockOutputStream
    org.apache.hadoop.net.ConnectTimeoutException: 60000 millis timeout while waiting for channel to be ready for connect. ch : java.nio.channels.SocketChannel[connection-pending remote=/x.x.x.x:50010]
            at org.apache.hadoop.net.NetUtils.connect(NetUtils.java:534)
            at org.apache.hadoop.hdfs.DataStreamer.createSocketForPipeline(DataStreamer.java:259)
            at org.apache.hadoop.hdfs.DataStreamer.createBlockOutputStream(DataStreamer.java:1692)
            at org.apache.hadoop.hdfs.DataStreamer.nextBlockOutputStream(DataStreamer.java:1648)
            at org.apache.hadoop.hdfs.DataStreamer.run(DataStreamer.java:704)
    18/06/14 17:29:41 WARN hdfs.DataStreamer: Abandoning BP-1801474405-10.0.0.4-1528990089179:blk_1073741825_1001
    18/06/14 17:29:41 WARN hdfs.DataStreamer: Excluding datanode DatanodeInfoWithStorage[10.0.0.6:50010,DS-d7d71735-7099-4aa9-8394-c9eccc325806,DISK]
    18/06/14 17:29:41 WARN hdfs.DataStreamer: DataStreamer Exception
    org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /test.txt._COPYING_ could only be replicated to 0 nodes instead of minReplication (=1).  There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
    

    如果我查看 Web UI,数据节点似乎已启动并且未报告任何问题...

    更新:swarm 似乎忽略了dependsOn,但它似乎不是我的问题的原因:当namenode 启动时,我已经重新启动了datanode,但它并没有更好地工作。

    谢谢你的帮助 :)

    最佳答案

    整个困惑源于使用覆盖网络的 docker swarm 之间的交互以及 HDFS 名称节点如何跟踪其数据节点。 namenode 根据 datanode 的覆盖网络 IPs 记录 datanode IPs/hostnames。当 HDFS 客户端直接在数据节点上请求读/写操作时,名称节点会根据覆盖网络报告数据节点的 IP/主机名。由于外部客户端无法访问覆盖网络,因此任何 rw 操作都将失败。

    我使用的最终解决方案(经过大量努力使覆盖网络正常工作)是让 HDFS 服务使用主机网络。这是撰写文件中的一个片段:

    version: '3.7'
    
    x-deploy_default: &deploy_default
      mode: replicated
      replicas: 1
      placement:
        constraints:
          - node.role == manager
      restart_policy:
        condition: any
        delay: 5s
    
    services:
      hdfs_namenode:
        deploy:
          <<: *deploy_default
        networks:
          hostnet: {}
        volumes:
          - hdfs_namenode:/hadoop-3.2.0/var/name_node
        command:
          namenode -fs hdfs://${PRIMARY_HOST}:9000
        image: hadoop:3.2.0
    
      hdfs_datanode:
        deploy:
          mode: global
        networks:
          hostnet: {}
        volumes:
          - hdfs_datanode:/hadoop-3.2.0/var/data_node
        command:
          datanode -fs hdfs://${PRIMARY_HOST}:9000
        image: hadoop:3.2.0
    volumes:
      hdfs_namenode:
      hdfs_datanode:
    
    networks:
      hostnet:
        external: true
        name: host
    

    关于docker - 如何使 HDFS 在 docker swarm 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50861281/

    相关文章:

    hadoop - 同步日志到hadoop的架构

    Hadoop:hdfs dfs -text 的倒数

    shell - 使用Dockerfile中的Shell脚本启动多个服务

    nginx - 一个nginx上的两个docker app容器

    docker - 如何更改 Kibana 的 Docker 镜像的端口号

    scala - 如何优化 spark 函数以将 double 值舍入为 2 位小数?

    hadoop - hdfs:无法放置足够的副本:预期大小为2,但只能选择0种存储类型

    sql - 无法在Hive的alter database语句中识别数据库SET LOCATION附近的输入

    hadoop - Partitioner 似乎不能在单个节点上工作?

    nginx - Docker 网络 - nginx : [emerg] host not found in upstream