Развертывание Spark и HDFS на Docker Swarm не обеспечивает локальность данных - PullRequest
6 голосов
/ 10 ноября 2019

Я пытаюсь настроить развертывание Spark + HDFS на небольшом кластере, используя Docker Swarm в качестве стекового развертывания. Обычно у меня это работает, но я столкнулся с проблемой, которая не позволяет Spark использовать преимущества локальности данных.

В попытке включить локальность данных я создал отдельный контейнер «рабочий узел» на каждом сервере, которыйсодержит рабочий Spark и датодую HDFS. Идея заключается в том, что они оба должны иметь один и тот же IP-адрес в оверлейной сети стека, поскольку они работают в одном контейнере. Однако они этого не делают. Казалось бы, контейнер получает один VIP в оверлейной сети, а служба, определенная в файле compose, который использует стек, получает другой VIP.

Оказывается, процесс процесса HDD datanode связывается с контейнерами VIP и Spark. Рабочий процесс привязывается к VIP-службе (насколько я могу определить). В результате Spark не знает, что рабочий Spark и датода данных HDFS фактически находятся на одном компьютере, и только планирует задачи с локальностью ANY.

Я уверен, что что-то упустил, но я (конечно) не знаю что.

Запись файла стека 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>

Моя полная настройка может быть просмотрена здесь на GitHub .

Есть ли у кого-нибудь идеи, что я делаю неправильно, что препятствует связыванию процессов Spark worker и HDFS datanode в одном и том же контейнере Docker с одним и тем же IP-адресом?

...