Использование JAR-файла в задании Azure Databricks
Архив Java или [JAR](https://en.wikipedia.org/wiki/JAR_(file_format) формат файла основан на популярном формате 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 и выполните одно из следующих действий:
- На боковой панели щелкните "Рабочие процессы" и щелкните .
- На боковой панели нажмите кнопку "Создать " и выберите "Задание " в меню.
- В диалоговом окне задачи, которое отображается на вкладке "Задачи ", замените имя задания... например
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 см. в статье "Планирование и оркестрация рабочих процессов".