Использование JAR-файла в задании Azure Databricks
Архив Java или JAR-файл основан на популярном формате ZIP-файла и используется для агрегирования множества файлов Java или Scala в один. С помощью задачи JAR можно обеспечить быструю и надежную установку кода Java или Scala в заданиях Azure Databricks. В этой статье приведен пример создания JAR-файла и задания, запускающего приложение, упаковаемое в JAR-файл. В этом примере вы будете:
- Создайте проект JAR, определяющий пример приложения.
- Упаковайте примеры файлов в JAR-файл.
- Создайте задание для запуска JAR-файла.
- Запустите задание и ознакомьтесь с результатами.
Перед началом работы
Для выполнения этого примера вам потребуется следующее:
- Для java JARs пакет средств разработки Java (JDK).
- Для Scala JARs, JDK и sbt.
Шаг 1. Создание локального каталога для примера
Создайте локальный каталог для хранения примера кода и созданных артефактов, например databricks_jar_test
.
Шаг 2. Создание JAR-файла
Выполните следующие инструкции, чтобы создать JAR-файл с помощью Java или Scala.
Создание JAR-файла Java
В папке
databricks_jar_test
создайте файл с именемPrintArgs.java
со следующим содержимым:import java.util.Arrays; public class PrintArgs { public static void main(String[] args) { System.out.println(Arrays.toString(args)); } }
PrintArgs.java
Скомпилируйте файл, создающий файлPrintArgs.class
:javac PrintArgs.java
(Необязательно) Запустите скомпилированную программу:
java PrintArgs Hello World! # [Hello, World!]
В той же папке, что
PrintArgs.java
иPrintArgs.class
файлы, создайте папку с именемMETA-INF
.В папке
META-INF
создайте файл с именемMANIFEST.MF
со следующим содержимым. Обязательно добавьте новую строку в конце этого файла:Main-Class: PrintArgs
В корне
databricks_jar_test
папки создайте JAR-файл с именемPrintArgs.jar
:jar cvfm PrintArgs.jar META-INF/MANIFEST.MF *.class
(Необязательно) Чтобы проверить его, запустите JAR-файл из корневого
databricks_jar_test
каталога:java -jar PrintArgs.jar Hello World! # [Hello, World!]
Примечание.
Если вы получите ошибку
no main manifest attribute, in PrintArgs.jar
, обязательно добавьте новую строку в конец файлаMANIFEST.MF
, а затем попробуйте создать и запустить JAR-файл еще раз.Отправка
PrintArgs.jar
в том. См. загрузку файлов в раздел каталога Unity.
Создание JAR-файла Scala
databricks_jar_test
Создайте пустой файлbuild.sbt
из папки со следующим содержимым:ThisBuild / scalaVersion := "2.12.14" ThisBuild / organization := "com.example" lazy val PrintArgs = (project in file(".")) .settings( name := "PrintArgs" )
databricks_jar_test
Создайте структуруsrc/main/scala/example
папок из папки.В папке
example
создайте файл с именемPrintArgs.scala
со следующим содержимым:package example object PrintArgs { def main(args: Array[String]): Unit = { println(args.mkString(", ")) } }
Скомпилируйте программу:
sbt compile
(Необязательно) Запустите скомпилированную программу:
sbt "run Hello World\!" # Hello, World!
В папке
databricks_jar_test/project
создайте файл с именемassembly.sbt
со следующим содержимым:addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0")
В корневой
databricks_jar_test
папке выполнитеassembly
команду, которая создает JAR-файл в папкеtarget
:sbt assembly
(Необязательно) Чтобы проверить его, запустите JAR-файл из корневого
databricks_jar_test
каталога:java -jar target/scala-2.12/PrintArgs-assembly-0.1.0-SNAPSHOT.jar Hello World! # Hello, World!
Отправка
PrintArgs-assembly-0.1.0-SNAPSHOT.jar
в том. См. загрузку файлов в раздел каталога Unity.
Шаг 3. Создание задания Azure Databricks для запуска JAR-файла
- Перейдите на целевую страницу Azure Databricks и выполните одно из следующих действий:
- На боковой панели щелкните "Рабочие процессыCreate Job Button" и щелкните .
Кнопка "Создать задание"
- На боковой панели щелкните
Создать и выберите задание в меню.
- На боковой панели щелкните "Рабочие процессыCreate Job Button" и щелкните .
- В диалоговом окне задачи, которое отображается на вкладке "Задачи ", замените имя задания... например
JAR example
. - В поле "Имя задачи" введите имя задачи, например
java_jar_task
Java илиscala_jar_task
Scala. - Для типавыберите JAR-.
- Для основного класса в этом примере введите
PrintArgs
для Java илиexample.PrintArgs
Scala. - Для кластеравыберите совместимый кластер. Ознакомьтесь с поддержкой библиотеки Java и Scala.
- Для зависимых библиотек нажмите кнопку +Добавить.
-
В диалоговом окне добавления зависимой библиотеки с выбранным Томов введите местоположение, куда вы загрузили JAR-файл (
PrintArgs.jar
илиPrintArgs-assembly-0.1.0-SNAPSHOT.jar
) на предыдущем шаге в путь к файлу Томов, или отфильтруйте список, или просмотрите, чтобы найти JAR-файл. Выберите его. - Нажмите кнопку Добавить.
- Для параметров введите
["Hello", "World!"]
. - Нажмите кнопку Добавить.
Шаг 4. Запуск задания и просмотр сведений о выполнении задания
Щелкните , чтобы запустить рабочий процесс. Чтобы просмотреть сведения о выполнении, щелкните Просмотреть выполнение в всплывающем окне Запущенного выполнения или щелкните ссылку в столбце Время начала для запуска в представлении выполнения заданий.
По завершении выполнения выходные данные отображаются на панели вывода , включая аргументы, переданные задаче.
Ограничения размера выходных данных для заданий JAR
Выходные данные задания, такие как выходные данные журнала, созданные в stdout, подлежат ограничению размера в 20 МБ. Если общий объем выходных данных имеет больший размер, выполнение отменяется и помечается как завершенное с ошибкой.
Чтобы избежать возникновения этого ограничения, можно прекратить возврат stdout из драйвера в Azure Databricks, настроив параметр spark.databricks.driver.disableScalaOutput
Spark в значении true
. По умолчанию флаг имеет значение false
. Флаг контролирует выходные данные ячейки для заданий JAR Scala и записных книжек Scala. Если флаг включен, Spark не возвращает клиенту результаты выполнения задания. Флаг не влияет на данные, записываемые в файлы журналов кластера. Databricks рекомендует задать этот флаг только для кластеров заданий JAR, так как он отключает результаты записной книжки.
Рекомендация. Использование общего доступа SparkContext
Так как Azure Databricks — это управляемая служба, некоторые изменения кода могут потребоваться для правильного выполнения заданий Apache Spark. Программы задания JAR должны использовать общий API SparkContext
для получения SparkContext
. Поскольку Azure Databricks инициализирует SparkContext
, программы, которые вызывают ошибку new SparkContext()
, завершаются с ошибкой. Чтобы получить SparkContext
, используйте только общие ресурсы SparkContext
, созданные с помощью Azure Databricks.
val goodSparkContext = SparkContext.getOrCreate()
val goodSparkSession = SparkSession.builder().getOrCreate()
Некоторых методов при использовании общего SparkContext
следует избегать.
- Не вызывайте
SparkContext.stop()
. - Не вызывайте
System.exit(0)
илиsc.stop()
в конце программыMain
. Это может привести к неопределенному поведению.
Рекомендация. Использование try-finally
блоков для очистки задания
Возьмем для примера JAR, состоящий из двух частей:
-
jobBody()
— содержит основную часть задания; -
jobCleanup()
который должен выполняться послеjobBody()
того, успешно ли эта функция выполнена или возвращена исключение.
Например, jobBody()
создает таблицы и jobCleanup()
удаляет эти таблицы.
Безопасный способ убедиться, что метод очистки вызывается, заключается в том, чтобы поместить try-finally
блок в код:
try {
jobBody()
} finally {
jobCleanup()
}
Не пытайтесь использовать для очистки sys.addShutdownHook(jobCleanup)
или следующий код:
val cleanupThread = new Thread { override def run = jobCleanup() }
Runtime.getRuntime.addShutdownHook(cleanupThread)
Так как время существования контейнеров Spark управляется в Azure Databricks, перехватчики завершения работы не выполняются надежно.
Настройка параметров задания JAR
Вы передаете параметры в задания JAR с массивом строк JSON. См. объект spark_jar_task
в тексте запроса, передаваемый в операцию Создать задачу (POST /jobs/create
) в API заданий. Чтобы получить доступ к этим параметрам, проверьте массив String
, переданный в функцию main
.
Управление зависимостями библиотек
Драйвер Spark имеет определенные зависимости библиотек, которые не могут быть переопределены. Если задание добавляет конфликтующие библиотеки, зависимости библиотеки драйверов Spark имеют приоритет.
Чтобы получить полный список зависимостей библиотеки драйверов, выполните следующую команду в записной книжке, подключенной к кластеру, настроенной с той же версией Spark (или кластером с драйвером, который требуется проверить):
%sh
ls /databricks/jars
При определении зависимостей библиотеки для JAR Databricks рекомендует перечислять Spark и Hadoop в качестве provided
зависимостей. В Maven добавьте Spark и Hadoop в качестве указанных зависимостей:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
<scope>provided</scope>
</dependency>
Добавьте sbt
Spark и Hadoop в качестве указанных зависимостей:
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.3.0" % "provided"
libraryDependencies += "org.apache.hadoop" %% "hadoop-core" % "1.2.1" % "provided"
Совет
Укажите правильную версию Scala для ваших зависимостей, исходя из используемой вами версии.
Дальнейшие действия
Дополнительные сведения о создании и запуске заданий Azure Databricks см. в Обзор оркестрации в Databricks.