Кластерные приложения на Docker
Кластер Apache Spark на Docker (с интерфейсом JupyterLab)
Создайте собственный кластер Apache Spark в автономном режиме на Docker с помощью интерфейса JupyterLab.
Apache Spark, пожалуй, самый популярный механизм обработки больших данных. Фреймворк с более чем 25 тысячами звезд на GitHub является отличной отправной точкой для изучения параллельных вычислений в распределенных системах с использованием Python, Scala и R.
Для начала вы можете запустить Apache Spark на своем компьютере, используя один из множества доступных доступных дистрибутивов Docker. Jupyter предлагает отличный dockerized Apache Spark с интерфейсом JupyterLab, но пропускает распределенное ядро фреймворка из-за его запуска в одном контейнере. Некоторые проекты GitHub предлагают возможности распределенного кластера, но не имеют интерфейса JupyterLab, что снижает удобство использования, обеспечиваемое IDE.
Я считаю, что комплексная среда для изучения и практики кода Apache Spark должна сохранять свою распределенную природу, обеспечивая при этом отличное взаимодействие с пользователем.
Эта статья полностью посвящена этой вере.
В следующих разделах я покажу вам, как построить собственный кластер. К концу у вас будет полнофункциональный кластер Apache Spark, построенный с помощью Docker и поставляемый с главным узлом Spark, двумя рабочими узлами Spark и интерфейсом JupyterLab. Он также будет включать API Apache Spark Python (PySpark) и смоделированную распределенную файловую систему Hadoop (HDFS).
TL;DR
В этой статье показано, как построить кластер Apache Spark в автономном режиме, используя Docker в качестве уровня инфраструктуры. Поставляется со следующим:
- Python 3.7 с PySpark 3.0.0 и Java 8;
- Apache Spark 3.0.0 с одним главным и двумя рабочими узлами;
- JupyterLab IDE 2.1.5;
- Имитация HDFS 2.7.
Чтобы создать кластер, нам нужно создать, собрать и скомпоновать образы Docker для узлов JupyterLab и Spark. Вы можете пропустить это руководство, используя готовый дистрибутив, размещенный на моем GitHub.
Обновление № 1. В 2020-08-09 мы выпустили поддержку Spark Scala API через ядро Almond Jupyter Scala. Спасибо, Алмонд, за то, что он классный. ✨
Обновление №2: В 2020–08–19 мы выпустили поддержку Spark R API (SparkR) через ядро IRkernel Jupyter R. Спасибо IRkernel за то, что они классные. ✨
Требования
- Docker 1.13.0+;
- Docker Compose 1.10.0+.
Оглавление
- Обзор кластера;
- Создание изображений;
- Построение образов;
- Составление кластера;
- Создание приложения PySpark.
1. Обзор кластера
Кластер состоит из четырех основных компонентов: IDE JupyterLab, главного узла Spark и двух рабочих узлов Spark. Пользователь подключается к главному узлу и отправляет команды Spark через красивый графический интерфейс, предоставляемый записными книжками Jupyter. Главный узел обрабатывает ввод и распределяет вычислительную нагрузку по рабочим узлам, отправляя результаты обратно в IDE. Компоненты соединены с помощью локальной сети и обмениваются данными друг с другом через общий смонтированный том, имитирующий HDFS.
Как уже упоминалось, нам нужно создать, собрать и скомпоновать образы Docker для узлов JupyterLab и Spark, чтобы создать кластер. Мы будем использовать следующую иерархию образов Docker:
Базовый образ кластера загрузит и установит стандартные программные инструменты (Java, Python и т. Д.) И создаст общий каталог для HDFS. В базовом образе Spark приложение Apache Spark будет загружено и настроено как для главного, так и для рабочего узлов. Главный образ Spark настроит платформу для работы в качестве главного узла. Точно так же рабочий узел Spark настроит приложение Apache Spark для работы в качестве рабочего узла. Наконец, образ JupyterLab будет использовать базовый образ кластера для установки и настройки IDE и PySpark, API Python Apache Spark.
2. Создание изображений
2.1. Базовый образ кластера
В качестве базового образа мы будем использовать дистрибутив Linux для установки Java 8 (или 11), только для Apache Spark. Нам также необходимо установить Python 3 для поддержки PySpark и создать общий том для имитации HDFS.
Для начала выберем ОС Linux. В официальном репозитории Apache Spark на GitHub есть Dockerfile для развертывания Kubernetes, в котором используется небольшой образ Debian со встроенной средой выполнения Java 8 (JRE). Выбирая тот же базовый образ, мы решаем как выбор ОС, так и установку Java. Затем мы получаем последний выпуск Python (в настоящее время 3.7) из официального репозитория пакетов Debian и создаем общий том.
2.2. Базовое изображение Spark
Для базового образа Spark мы получим и настроим Apache Spark в автономном режиме, в его простейшей конфигурации развертывания. В этом режиме мы будем использовать его диспетчер ресурсов для настройки контейнеров для работы в качестве главного или рабочего узла. Напротив, менеджеры ресурсов, такие как Apache YARN, динамически выделяют контейнеры в качестве главных или рабочих узлов в соответствии с рабочей нагрузкой пользователя. Кроме того, мы получим версию Apache Spark с поддержкой Apache Hadoop, позволяющую кластеру моделировать HDFS с использованием общего тома, созданного в базовом образе кластера.
Начнем с загрузки последней версии Apache Spark (в настоящее время 3.0.0) с поддержкой Apache Hadoop из официального репозитория Apache. Затем мы немного поиграем с загруженным пакетом (распаковываем, перемещаем и т. Д.), И мы готовы к этапу установки. Наконец, мы настраиваем четыре переменные Spark, общие как для главного, так и для рабочих узлов:
- SPARK_HOME - это установленное расположение Apache Spark, используемое платформой для настройки задач;
- SPARK_MASTER_HOST - это имя хоста главного узла, используемое рабочими узлами для подключения;
- SPARK_MASTER_PORT - это порт главного узла, используемый рабочими узлами для подключения;
- PYSPARK_PYTHON - это установленная папка Python, используемая Apache Spark для поддержки своего Python API.
2.3. Главный образ Spark
Для главного образа Spark мы настроим приложение Apache Spark для работы в качестве главного узла. Мы настроим сетевые порты, чтобы разрешить сетевое соединение с рабочими узлами и открыть главный веб-интерфейс, веб-страницу для мониторинга действий главного узла. В конце мы настроим команду запуска контейнера для запуска узла в качестве главного экземпляра.
Мы начинаем с открытия порта, настроенного в переменной среды SPARK_MASTER_PORT, чтобы рабочие могли подключаться к главному узлу. Затем мы открываем порт SPARK_MASTER_WEBUI_PORT для доступа к главной странице веб-интерфейса. Наконец, мы устанавливаем команду запуска контейнера для запуска встроенного сценария развертывания Spark с мастер-классом в качестве аргумента.
2.4. Образ рабочего Spark
Для рабочего образа Spark мы настроим приложение Apache Spark для работы в качестве рабочего узла. Подобно главному узлу, мы настроим сетевой порт, чтобы открыть рабочий веб-интерфейс, веб-страницу для мониторинга активности рабочего узла и настроить команду запуска контейнера для запуска узла в качестве рабочего экземпляра.
Сначала мы открываем порт SPARK_WORKER_WEBUI_PORT, чтобы разрешить доступ к странице рабочего веб-интерфейса пользователя, как мы это сделали с главным узлом. Затем мы устанавливаем команду запуска контейнера для запуска встроенного сценария развертывания Spark с рабочим классом и основным сетевым адресом в качестве аргументов. Это заставит рабочие узлы подключаться к главному узлу в процессе его запуска.
2.5. Изображение JupyterLab
Для образа JupyterLab мы вернемся немного назад и снова начнем с базового образа кластера. Мы установим и настроим IDE вместе с дистрибутивом Apache Spark, который немного отличается от того, который установлен на узлах Spark.
Мы начинаем с установки pip, диспетчера пакетов Python и инструментов разработки Python, которые позволяют устанавливать пакеты Python во время создания образа и во время выполнения контейнера. Затем возьмем JupyterLab и PySpark из индекса пакетов Python (PyPI). Наконец, мы открываем порт по умолчанию, чтобы разрешить доступ к веб-интерфейсу JupyterLab, и устанавливаем команду запуска контейнера для запуска приложения IDE.
3. Создание образов
Образы Docker готовы, давайте их создадим. Обратите внимание: поскольку мы использовали ключевое слово Docker arg в файлах Docker для указания версий программного обеспечения, мы можем легко изменить версии Apache Spark и JupyterLab по умолчанию для кластера.
4. Составление кластера
Файл компоновки Docker содержит рецепт для нашего кластера. Здесь мы создадим контейнеры узлов JuyterLab и Spark, предоставим их порты для локальной сети и подключим их к смоделированной HDFS.
Начнем с создания тома Docker для смоделированной HDFS. Затем мы создаем по одному контейнеру для каждого компонента кластера. Контейнер jupyterlab предоставляет порт IDE и связывает свой общий каталог рабочей области с томом HDFS. Точно так же контейнер spark-master предоставляет свой порт веб-интерфейса и порт подключения master-worker, а также привязывается к тому HDFS.
Мы завершаем создание двух рабочих контейнеров Spark с именами spark-worker-1 и spark-worker-2. Каждый контейнер предоставляет свой порт веб-интерфейса (сопоставлен с 8081 и 8082 соответственно) и привязывается к тому HDFS. У этих контейнеров есть шаг среды, который определяет их аппаратное распределение:
- SPARK_WORKER_CORE - количество ядер;
- SPARK_WORKER_MEMORY - объем оперативной памяти.
По умолчанию мы выбираем одно ядро и 512 МБ ОЗУ для каждого контейнера. Не стесняйтесь играть с распределением оборудования, но обязательно соблюдайте ограничения вашего компьютера, чтобы избежать проблем с памятью. Кроме того, предоставьте приложению Docker достаточно ресурсов для обработки выбранных значений.
Чтобы собрать кластер, запустите файл компоновки Docker:
После завершения проверьте веб-интерфейс компонентов:
- JupyterLab по адресу localhost: 8888;
- Мастер Spark по адресу localhost: 8080;
- Spark worker I на localhost: 8081;
- Spark worker II на localhost: 8082;
5. Создание приложения PySpark
Когда наш кластер запущен и работает, давайте создадим наше первое приложение PySpark.
Откройте IDE JupyterLab и создайте записную книжку Python Jupyter. Создайте приложение PySpark, подключившись к главному узлу Spark с помощью объекта сеанса Spark со следующими параметрами:
- appName - это имя нашего приложения;
- master - это главный URL-адрес подключения Spark, тот же самый, который используется рабочими узлами Spark для подключения к главному узлу Spark;
- config - это общая конфигурация Spark для автономного режима. Здесь мы сопоставляем память исполнителя, то есть рабочий процесс JVM Spark, с выделенной памятью рабочего узла.
Запустите ячейку, и вы сможете увидеть приложение, указанное в разделе Запущенные приложения в главном веб-интерфейсе Spark. Затем мы загружаем набор данных радужки из репозитория UCI в смоделированную HDFS. Наконец, мы читаем и распечатываем данные с помощью PySpark.
Это все, ребята. Надеюсь, я помог вам узнать немного больше о внутреннем устройстве Apache Spark и о том, как работают распределенные приложения. Удачного обучения!