在 Docker Swarm 上部署 Spark 和 HDFS 不会启用数据本地化

Posted

技术标签:

【中文标题】在 Docker Swarm 上部署 Spark 和 HDFS 不会启用数据本地化【英文标题】:Deploying Spark and HDFS on Docker Swarm doesn't enable data locality 【发布时间】:2020-03-06 01:59:22 【问题描述】:

我正在尝试使用 Docker Swarm 作为堆栈部署在小型集群上设置 Spark + HDFS 部署。我可以正常工作,但我遇到了一个问题,它阻止 Spark 充分利用数据局部性。

为了启用数据局部性,我在每台服务器上创建了一个“工作节点”容器,其中包含 Spark 工作程序和 HDFS 数据节点。这里的想法是,它们应该在堆栈的覆盖网络上具有相同的 IP 地址,因为它们在同一个容器中运行。但是,他们没有。看起来容器在覆盖网络上获得了一个 VIP,而在堆栈使用的 compose 文件中定义的服务获得了另一个 VIP。

事实证明,HDFS 数据节点进程绑定到容器 VIP,而 Spark 工作进程绑定到服务的 VIP(据我所知)。因此,Spark 并不知道 Spark worker 和 HDFS datanode 实际上在同一台机器上,并且只调度具有ANY locality 的任务。

我确定我错过了什么,但我(当然)不知道是什么。

我用于定义每个工作节点服务的 Docker 堆栈组合文件条目如下所示:

version: '3.4'
services:

    ...

    worker-node2:
        image: master:5000/spark-hdfs-node:latest
        hostname: "worker-node2"
        networks:
            - cluster_network
        environment:
            - SPARK_PUBLIC_DNS=10.1.1.1
            - SPARK_LOG_DIR=/data/spark/logs
        depends_on:
            - hdfs-namenode
        volumes:
            - type: bind
              source: /mnt/data/hdfs
              target: /data/hdfs
            - type: bind
              source: /mnt/data/spark
              target: /data/spark
        deploy:
            mode: replicated
            replicas: 1
            placement:
                constraints:
                    - node.hostname == slave1
            resources:
               limits:
                   memory: 56g

    ...

networks:
    cluster_network:
        attachable: true
        ipam:
            driver: default
            config:
                - subnet: 10.20.30.0/24

Hadoop HDFS-site.xml 配置如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/data/hdfs/datanode</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/data/hdfs/namenode</value>
    </property>
    <property>
        <name>dfs.replication</name>
        <value>2</value>
        <description>The default replication factor of files on HDFS</description>
    </property>
    <property>
        <name>dfs.webhdfs.enabled</name>
        <value>true</value>
    </property>
    <property> 
        <name>dfs.block.size</name>
        <value>64m</value>
        <description>The default block size in bytes of data saved to HDFS</description>
    </property>
    <property>
        <name>dfs.namenode.datanode.registration.ip-hostname-check</name>
        <value>false</value>
    </property>
    <property>
        <name>dfs.client.use.datanode.hostname</name>
        <value>true</value>
    </property>
    <property>
        <name>dfs.datanode.use.datanode.hostname</name>
        <value>true</value>
    </property>

    <property>
        <name>dfs.namenode.rpc-bind-host</name>
        <value>0.0.0.0</value>
        <description>
            controls what IP address the NameNode binds to. 
            0.0.0.0 means all available.
        </description>
    </property>
    <property>
        <name>dfs.namenode.servicerpc-bind-host</name>
        <value>0.0.0.0</value>
        <description>
            controls what IP address the NameNode binds to. 
            0.0.0.0 means all available.
        </description>
    </property>
    <property>
        <name>dfs.namenode.http-bind-host</name>
        <value>0.0.0.0</value>
        <description>
            controls what IP address the NameNode binds to. 
            0.0.0.0 means all available.
        </description>
    </property>
    <property>
        <name>dfs.namenode.https-bind-host</name>
        <value>0.0.0.0</value>
        <description>
            controls what IP address the NameNode binds to. 
            0.0.0.0 means all available.
        </description>
    </property>

</configuration>

我的完整设置可以是viewed here on GitHub。

有没有人知道我做错了什么,阻止了同一个 Docker 容器中的 Spark 工作程序和 HDFS 数据节点进程绑定到同一个 IP 地址?

【问题讨论】:

一个典型的问题!这些天很少见! 您的 docker 引擎在什么主机操作系统上运行? Ubuntu 服务器 18.04.3 其默认情况下,服务发现会为 swarm 中的每个服务分配一个虚拟 IP 地址 (VIP) 和 DNS 条目,使其通过其服务名称可用于同一网络上的容器。您可以配置服务使用 DNS 循环而不是 VIP。来源:***.com/questions/38812357/… Docker 使用嵌入式 DNS 为在单个 Docker 引擎上运行的容器和在 Docker Swarm 中运行的任务提供服务发现。 Docker 引擎有一个内部 DNS 服务器,它为用户定义的桥接、覆盖和 MACVLAN 网络中主机上的所有容器提供名称解析。来源:***.com/questions/44724497/… 【参考方案1】:

这不是和这个的使用有关吗:

    <property>
        <name>dfs.client.use.datanode.hostname</name>
        <value>true</value>
    </property>

如果我没记错的话,使用主机名意味着绑定到容器而不是服务本身。

【讨论】:

在问题hostname: 设置为服务名称,虽然

以上是关于在 Docker Swarm 上部署 Spark 和 HDFS 不会启用数据本地化的主要内容,如果未能解决你的问题,请参考以下文章

在 ubuntu 20.04 上部署 docker 容器到 swarm 时出现 br_netfilter 错误

使用docker-compose.yml在swarm中部署应用

Docker-Swarm三节点部署

将 Docker 容器部署到 swarm 集群中的多个节点

如何使用未部署在 swarm 中的 docker 容器从 docker swarm 访问服务?

docker-swarm集群部署