Używanie pliku JAR w zadaniu usługi Azure Databricks

Archiwum Java lub [JAR](https://en.wikipedia.org/wiki/JAR_(file_format) format pliku jest oparty na popularnym formacie pliku ZIP i służy do agregowania wielu plików Java lub Scala w jeden. Za pomocą zadania JAR możesz zapewnić szybką i niezawodną instalację kodu Java lub Scala w zadaniach usługi Azure Databricks. Ten artykuł zawiera przykład tworzenia pliku JAR i zadania, które uruchamia aplikację spakowana w pliku JAR. W tym przykładzie wykonasz następujące elementy:

  • Utwórz projekt JAR definiujący przykładową aplikację.
  • Dołącz przykładowe pliki do pliku JAR.
  • Utwórz zadanie uruchamiania pliku JAR.
  • Uruchom zadanie i wyświetl wyniki.

Przed rozpoczęciem

Aby ukończyć ten przykład, potrzebne są następujące elementy:

  • W przypadku zestawów JAVA JARs zestaw Java Development Kit (JDK).
  • W przypadku zestawów JAR Scala zestaw JDK i sbt.

Krok 1. Tworzenie katalogu lokalnego na potrzeby przykładu

Utwórz katalog lokalny do przechowywania przykładowego kodu i wygenerowanych artefaktów, na przykład databricks_jar_test.

Krok 2. Tworzenie pliku JAR

Wykonaj poniższe instrukcje, aby utworzyć plik JAR przy użyciu języka Java lub Języka Scala.

Tworzenie pliku JAR w języku Java

  1. W folderze databricks_jar_test utwórz plik o nazwie o PrintArgs.java następującej zawartości:

    import java.util.Arrays;
    
    public class PrintArgs {
      public static void main(String[] args) {
        System.out.println(Arrays.toString(args));
      }
    }
    
  2. Skompiluj PrintArgs.java plik, który tworzy plik PrintArgs.class:

    javac PrintArgs.java
    
  3. (Opcjonalnie) Uruchom skompilowany program:

    java PrintArgs Hello World!
    
    # [Hello, World!]
    
  4. W tym samym folderze co PrintArgs.java pliki i PrintArgs.class utwórz folder o nazwie META-INF.

  5. W folderze META-INF utwórz plik o nazwie MANIFEST.MF o następującej zawartości. Pamiętaj, aby dodać nowy wiersz na końcu tego pliku:

    Main-Class: PrintArgs
    
  6. W katalogu głównym databricks_jar_test folderu utwórz plik JAR o nazwie PrintArgs.jar:

    jar cvfm PrintArgs.jar META-INF/MANIFEST.MF *.class
    
  7. (Opcjonalnie) Aby go przetestować, w katalogu głównym databricks_jar_test folderu uruchom plik JAR:

    java -jar PrintArgs.jar Hello World!
    
    # [Hello, World!]
    

    Uwaga

    Jeśli wystąpi błąd no main manifest attribute, in PrintArgs.jar, pamiętaj o dodaniu nowego wiersza na końcu MANIFEST.MF pliku, a następnie spróbuj ponownie utworzyć plik JAR i uruchomić go ponownie.

  8. Przekaż PrintArgs.jar do woluminu. Zobacz Przekazywanie plików do woluminu wykazu aparatu Unity.

Tworzenie pliku JAR języka Scala

  1. W folderze databricks_jar_test utwórz pusty plik o nazwie build.sbt o następującej zawartości:

    ThisBuild / scalaVersion := "2.12.14"
    ThisBuild / organization := "com.example"
    
    lazy val PrintArgs = (project in file("."))
      .settings(
        name := "PrintArgs"
      )
    
  2. W folderze databricks_jar_test utwórz strukturę src/main/scala/examplefolderów .

  3. W folderze example utwórz plik o nazwie o PrintArgs.scala następującej zawartości:

    package example
    
    object PrintArgs {
      def main(args: Array[String]): Unit = {
        println(args.mkString(", "))
      }
    }
    
  4. Skompiluj program:

    sbt compile
    
  5. (Opcjonalnie) Uruchom skompilowany program:

    sbt "run Hello World\!"
    
    # Hello, World!
    
  6. W folderze databricks_jar_test/project utwórz plik o nazwie o assembly.sbt następującej zawartości:

    addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0")
    
  7. W katalogu głównym databricks_jar_test folderu uruchom assembly polecenie , które generuje plik JAR w folderze target :

    sbt assembly
    
  8. (Opcjonalnie) Aby go przetestować, w katalogu głównym databricks_jar_test folderu uruchom plik JAR:

    java -jar target/scala-2.12/PrintArgs-assembly-0.1.0-SNAPSHOT.jar Hello World!
    
    # Hello, World!
    
  9. Przekaż PrintArgs-assembly-0.1.0-SNAPSHOT.jar do woluminu. Zobacz Przekazywanie plików do woluminu wykazu aparatu Unity.

Krok 3. Tworzenie zadania usługi Azure Databricks w celu uruchomienia pliku JAR

  1. Przejdź do strony docelowej usługi Azure Databricks i wykonaj jedną z następujących czynności:
    • Na pasku bocznym kliknij pozycję Ikona zadańPrzepływy pracy, a następnie kliknij pozycję Przycisk Utwórz zadanie.
    • Na pasku bocznym kliknij pozycję Nowa ikonaNowy i wybierz z menu pozycję Zadanie .
  2. W oknie dialogowym zadania wyświetlonym na karcie Zadania zastąp ciąg Dodaj nazwę zadania... nazwą zadania, na przykład JAR example.
  3. W polu Nazwa zadania wprowadź nazwę zadania, na przykład java_jar_task dla języka Java lub scala_jar_task scala.
  4. W polu Typ wybierz pozycję JAR.
  5. W polu Klasa Main w tym przykładzie wprowadź ciąg PrintArgs Java lub example.PrintArgs Scala.
  6. W polu Klaster wybierz zgodny klaster. Zobacz Obsługa bibliotek Java i Scala.
  7. W obszarze Biblioteki zależne kliknij pozycję + Dodaj.
  8. W oknie dialogowym Dodawanie biblioteki zależnej z wybraną pozycją Woluminy wprowadź lokalizację, w której przekazano plik JAR (PrintArgs.jar lub PrintArgs-assembly-0.1.0-SNAPSHOT.jar) w poprzednim kroku do ścieżki pliku woluminów, lub filtruj lub przeglądaj, aby znaleźć plik JAR. Wybierz je.
  9. Kliknij przycisk Dodaj.
  10. W polu Parametry w tym przykładzie wprowadź wartość ["Hello", "World!"].
  11. Kliknij przycisk Dodaj.

Krok 4. Uruchamianie zadania i wyświetlanie szczegółów przebiegu zadania

Kliknij Przycisk Uruchom teraz , aby uruchomić przepływ pracy. Aby wyświetlić szczegóły przebiegu, kliknij pozycję Wyświetl przebieg w wyskakującym oknie podręcznym Wyzwalane uruchomienie lub kliknij link w kolumnie Godzina rozpoczęcia przebiegu w widoku przebiegówzadań.

Po zakończeniu przebiegu dane wyjściowe zostaną wyświetlone w panelu Dane wyjściowe , w tym argumenty przekazane do zadania.

Limity rozmiaru danych wyjściowych dla zadań JAR

Dane wyjściowe zadania, takie jak dane wyjściowe dziennika emitowane do stdout, podlegają limitowi rozmiaru 20 MB. Jeśli łączny rozmiar danych wyjściowych jest większy, przebieg zostanie anulowany i oznaczony jako niepowodzenie.

Aby uniknąć napotkania tego limitu, możesz uniemożliwić powrót ze sterownika do usługi Azure Databricks przez ustawienie spark.databricks.driver.disableScalaOutput konfiguracji platformy Spark na truewartość . Domyślnie wartość flagi to false. Flaga steruje danymi wyjściowymi komórek dla zadań JAR języka Scala i notesów Scala. Jeśli flaga jest włączona, platforma Spark nie zwraca wyników wykonywania zadań do klienta. Flaga nie ma wpływu na dane zapisywane w plikach dziennika klastra. Usługa Databricks zaleca ustawienie tej flagi tylko dla klastrów zadań dla zadań JAR, ponieważ wyłącza wyniki notesu.

Zalecenie: użyj udostępnionego elementu SparkContext

Ponieważ usługa Azure Databricks jest usługą zarządzaną, niektóre zmiany kodu mogą być konieczne, aby upewnić się, że zadania platformy Apache Spark działają poprawnie. Programy zadań JAR muszą używać udostępnionego SparkContext interfejsu API, aby pobrać plik SparkContext. Ponieważ usługa Azure Databricks inicjuje SparkContextprogram , które wywołują new SparkContext() , nie powiedzie się. Aby pobrać element , użyj tylko udostępnionego elementu SparkContext utworzonego przez usługę SparkContextAzure Databricks:

val goodSparkContext = SparkContext.getOrCreate()
val goodSparkSession = SparkSession.builder().getOrCreate()

Istnieje również kilka metod, których należy unikać podczas korzystania z udostępnionego SparkContextelementu .

  • Nie należy wywoływać metody SparkContext.stop().
  • Nie należy wywoływać System.exit(0) ani sc.stop() na końcu Main programu. Może to spowodować niezdefiniowane zachowanie.

Zalecenie: Używanie try-finally bloków do czyszczenia zadania

Rozważ plik JAR składający się z dwóch części:

  • jobBody() który zawiera główną część zadania.
  • jobCleanup() które należy wykonać po jobBody(), czy ta funkcja powiodła się, czy zwróciła wyjątek.

Na przykład jobBody() tworzy tabele i jobCleanup() odrzuca te tabele.

Bezpiecznym sposobem zapewnienia, że wywoływana jest metoda czyszczenia, jest umieszczenie try-finally bloku w kodzie:

try {
  jobBody()
} finally {
  jobCleanup()
}

Nie należy próbować czyścić przy użyciu ani sys.addShutdownHook(jobCleanup) następującego kodu:

val cleanupThread = new Thread { override def run = jobCleanup() }
Runtime.getRuntime.addShutdownHook(cleanupThread)

Ze względu na sposób, w jaki okres istnienia kontenerów platformy Spark jest zarządzany w usłudze Azure Databricks, haki zamykania nie są uruchamiane niezawodnie.

Konfigurowanie parametrów zadania JAR

Parametry są przekazywane do zadań JAR z tablicą ciągów JSON. spark_jar_task Zobacz obiekt w treści żądania przekazany do operacji Tworzenie nowego zadania (POST /jobs/create) w interfejsie API zadań. Aby uzyskać dostęp do tych parametrów, sprawdź tablicę String przekazaną do funkcji main .

Zarządzanie zależnościami biblioteki

Sterownik platformy Spark ma pewne zależności biblioteki, których nie można zastąpić. Jeśli zadanie dodaje biblioteki powodujące konflikt, pierwszeństwo mają zależności biblioteki sterowników platformy Spark.

Aby uzyskać pełną listę zależności biblioteki sterowników, uruchom następujące polecenie w notesie dołączonym do klastra skonfigurowanego przy użyciu tej samej wersji platformy Spark (lub klastra ze sterownikiem, który chcesz zbadać):

%sh
ls /databricks/jars

Podczas definiowania zależności bibliotek dla jednostek JARs usługa Databricks zaleca wyświetlenie listy platform Spark i Hadoop jako provided zależności. W narzędziu Maven dodaj platformę Spark i platformę Hadoop zgodnie z podanymi zależnościami:

<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>

W sbtsystemie dodaj platformę Spark i platformę Hadoop zgodnie z podanymi zależnościami:

libraryDependencies += "org.apache.spark" %% "spark-core" % "2.3.0" % "provided"
libraryDependencies += "org.apache.hadoop" %% "hadoop-core" % "1.2.1" % "provided"

Napiwek

Określ poprawną wersję języka Scala dla zależności na podstawie używanej wersji.

Następne kroki

Aby dowiedzieć się więcej na temat tworzenia i uruchamiania zadań usługi Azure Databricks, zobacz Tworzenie i uruchamianie zadań usługi Azure Databricks.