Доступ к пользовательским JAR из Spark-заданий на AWS EMR

Автор Категория ,
Доступ к пользовательским JAR из Spark-заданий на AWS EMR

В рамках обучения разработчиков распределенных Spark-приложений, сегодня рассмотрим, как добавить функции из пользовательских JAR-файлов в кластер AWS EMR. Достоинства и недостатки действия начальной загрузки EMR с переопределением конфигурации Spark, а также расширенное управление зависимостями через spark-submit.

Трудности обращения к пользовательским JAR в Amazon EMR с Apache Spark и Livy

На практике довольно часто случается ситуация, когда требуется отправить собственный JAR с некоторыми дополнительными библиотеками, например, источниками данных для пользовательских форматов в кластер Amazon EMR с Apache Spark и Livy. Считается, что Amazon EMR как мощная облачная платформа больших данных отлично подходит для выполнения распределенных заданий Apache Spark. Однако содержимое JAR недоступно при попытке получить к нему доступ из Livy – REST-API сервиса для взаимодействия с кластером Spark. По сути, Apache Livy – это агент для запросов Spark, который отправляет код в кластер в виде фрагментов скрипта или пакетов. При этом он предоставляет программный RESTfull API для Java, Scala и Python, чтобы удаленное приложение выполняло код внутри Spark без необходимости поддерживать локальный контекст. Подробнее об этом мы писали здесь и здесь.

Например, есть задание для обработки данных и загрузки их в базу данных, которая доступна через коннектор в виде JAR. Необходимо запустить это задание на AWS EMR, поэтому JAR-коннектор должен быть доступен для кластера Spark. Или задание, содержащее зависимость, например, стороннюю библиотеку, упакованную в JAR, которая должна быть доступна при использовании с Livy.

Обеспечить доступ к функциям из пользовательских JAR-файлов в кластере AWS EMR можно одним из следующих способов:

  • действие начальной загрузки EMR с переопределением конфигурации Spark;
  • расширенное управление зависимостями через spark-submit.

Достоинства и недостатки каждого подхода мы рассмотрим далее.

Начальная загрузка EMR

Для решения вышеописанной проблемы можно использовать действие начальной загрузки EMR. Это предполагает отправку JAR-файла на узлы в кластере, чтобы сделать его доступным через переопределение конфигурации Spark. Сперва следует поместить файл JAR-библиотеки, созданной с помощью сборки sbt со всеми необходимыми зависимостями в корзину S3. Затем нужно создать скрипт для копирования JAR на узел кластера, который содержит следующее:

#!/bin/bash

mkdir -p /home/hadoop/mylib

aws s3 cp s3://mybucket/mylib.jar/home/hadoop/mylib

Этот скрипт будет настроен как действие начальной загрузки в EMR, поэтому он будет выполняться на каждом узле после его подготовки.

Наконец, нужно переопределить конфигурации Spark, чтобы включить JAR в путь к классам. Здесь стоит убедиться, что JAR добавлен в задание через свойства spark.driver.extraClassPath и spark.executor.extraClassPath в spark-submit с помощью конфигурации JSON при создании кластера. Конфигурацию JSON помещается в туже корзину AWS S3, где лежат JAR-файл и скрипт для его копирования на узел кластера.

Конфигурации для сред Spark и YARN нужны, чтобы PySpark работал с Python3 в EMR через Livy. По умолчанию AWS EMR сам заполняет два класса extraClassPath множеством библиотек, которые требуются для правильной работы этой облачной платформы. Поэтому приходится запускать кластер без пользовательской библиотеки JAR и извлекать эти настройки из конфигурационного файла spark-defaults.conf, чтобы настроить собственную конфигурацию. Иначе доступ к S3 не будет работать.

Таким образом, при создании кластера на шаге 1 следует сослаться на файл конфигурации JSON, а на шаге 3 – настроить скрипт копирования JAR-файла как пользовательское действие начальной загрузки. Далее можно открыть Jupyterhub кластера, запустить блокнот и работать с добавленными функциями.

Этот подход работает, но имеет несколько недостатков:

  • необходима ручная проверка, что конфигурация driver.extraClassPath и spark.executor.extraClassPath синхронизирована с путями к зависимостям, необходимым для работы EMR с учетом актуальной версии платформы;
  • усложнение процесса создания кластера EMR, т.к. сюда включается действие начальной загрузки и переопределение конфигурации Spark. Из-за ошибки на этих шагах придется заново создавать EMR или копировать JAR на все узлы вручную, а также устанавливать driver.extraClassPath и spark.executor.extraClassPath как часть spark-submit. Также это увеличивает время создания кластера EMR.

Чтобы избежать указанных недостатков, можно использовать альтернативный способ, рассмотренный далее.

Альтернативный подход

Добавить функции из пользовательских JAR-файлов в кластер AWS EMR без действия начальной загрузки и переопределения конфигурации Spark можно с помощью расширенного управления зависимостями через spark-submit – скрипт для распределения заданий независимо от типа диспетчера кластера. Он позволяет запускать код Apache Spark, написанный на Java, Scala или Python.

Spark-submit имеет параметр –jars для отправки JAR-файлов на узлы в кластере и делает их доступными в пути к классам всех исполнителей. При этом JAR-файл приложения вместе со всеми JAR-файлами, включенными в spark-submit с параметром –jars, будут автоматически перенесены в кластер. URL-адреса, указанные после опции –jars, должны быть разделены запятыми. Этот список включен в пути к классам драйвера и исполнителя. Расширение каталога не работает с параметром –jars.

Spark использует следующую схему URL-адресов, позволяющую использовать различные стратегии распространения JAR-файлов:

  • file: – абсолютные пути и URI-адреса file:/ обслуживаются файловым HTTP-сервером драйвера, и каждый исполнитель извлекает файл с HTTP-сервера драйвера;
  • hdfs:, http:, https:, ftp: – эти файлы и JAR-файлы вытягиваются из URI;
  • local: – ожидается, что URI, начинающийся с local:/, будет существовать как локальный файл на каждом рабочем узле. Это означает, что сетевой ввод-вывод не будет выполняться, что отлично подходит для работы с большими файлами, которые передаются каждому рабочему процессу или совместно используются через NFS, GlusterFS и прочие сетевые файловые системы.

Поскольку файлы копируются в рабочий каталог для каждого SparkContext на узлах-исполнителях, в перспективе это может занимать много места на дисках и их придется чистить. В YARN очистка выполняется автоматически, а в автономном режиме Spark автоматическую очистку можно настроить с помощью свойства spark.worker.cleanup.appDataTtl.

Data Pipeline на Apache Airflow и Apache Hadoop

Код курса
AIRF
Ближайшая дата курса
15 июня, 2022
Длительность обучения
24 ак.часов
Стоимость обучения
60 000 руб.

Пользователи также могут включать любые другие зависимости, указав разделенный запятыми список координат Maven с опцией –packages. Все транзитивные зависимости будут обработаны при использовании этой команды. Дополнительные репозитории или распознаватели в sbt можно добавлять через запятую с помощью флага –repositories. При этом учетные данные для защищенных паролем репозиториев могут быть предоставлены в их URI, например, https://user:password@host/. Поэтому применять подобные команды следует очень осторожно. Эти команды могут использоваться с pyspark, spark-shell и spark-submit для включения пакетов Spark.

Для Python можно использовать эквивалентную опцию –py-files, чтобы распространить библиотеки .egg, .zip и .py по исполнителям.

Поскольку EMR может обращаться к S3 как к файловой системе, через spark-submit можно передать сам путь к корзине в параметре –jars. Например,

spark-submit –deploy-mode cluster –jars s3://my-bucket/my-jars/db-connector.jar …

spark-submit –deploy-mode cluster –jars s3://my-bucket/my-jars/*.jar …

Таким образом, все JAR-файлы с зависимостями будут скопированы в кластер AWS EMR и можно использовать любой JAR из S3, пропустив добавление действия начальной загрузки во время создания кластера. Это позволяет сделать любой JAR в S3 доступным для заданий Spark как часть отправки задания и избежать дополнительных шагов при создании кластера AWS EMR.

Узнайте больше про применение Apache Spark для разработки распределенных ML-приложений и аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Источники

  1. https://arunvelsriram.dev/adding-custom-jars-to-spark-jobs-on-aws-emr
  2. https://stackoverflow.com/questions/56666457/how-to-add-functions-from-custom-jars-to-emr-cluster/56667997#56667997
  3. https://spark.apache.org/docs/latest/submitting-applications.html#advanced-dependency-management