Använda en JAR i ett Azure Databricks-jobb

Java-arkivet eller [JAR](https://en.wikipedia.org/wiki/JAR_(file_format) filformatet baseras på det populära ZIP-filformatet och används för att aggregera många Java- eller Scala-filer till en. Med hjälp av JAR-uppgiften kan du säkerställa snabb och tillförlitlig installation av Java- eller Scala-kod i dina Azure Databricks-jobb. Den här artikeln innehåller ett exempel på hur du skapar en JAR-fil och ett jobb som kör programmet som paketeras i JAR-filen. I det här exemplet kommer du att:

  • Skapa JAR-projektet som definierar ett exempelprogram.
  • Paketera exempelfilerna i en JAR-fil.
  • Skapa ett jobb för att köra JAR-filen.
  • Kör jobbet och visa resultatet.

Innan du börjar

Du behöver följande för att slutföra det här exemplet:

  • Java Development Kit (JDK) för Java JARs.
  • För Scala JARs, JDK och sbt.

Steg 1: Skapa en lokal katalog för exemplet

Skapa en lokal katalog för att lagra exempelkoden och genererade artefakter, till exempel databricks_jar_test.

Steg 2: Skapa JAR-filen

Följ anvisningarna nedan om du vill använda Java eller Scala för att skapa JAR-filen.

Skapa en Java JAR

  1. Från mappen databricks_jar_test skapar du en fil med namnet PrintArgs.java med följande innehåll:

    import java.util.Arrays;
    
    public class PrintArgs {
      public static void main(String[] args) {
        System.out.println(Arrays.toString(args));
      }
    }
    
  2. Kompilera PrintArgs.java filen, som skapar filen PrintArgs.class:

    javac PrintArgs.java
    
  3. (Valfritt) Kör det kompilerade programmet:

    java PrintArgs Hello World!
    
    # [Hello, World!]
    
  4. Skapa en mapp med namnet META-INFi samma mapp som PrintArgs.java filerna och PrintArgs.class .

  5. I mappen META-INF skapar du en fil med namnet MANIFEST.MF med följande innehåll. Se till att lägga till en ny rad i slutet av den här filen:

    Main-Class: PrintArgs
    
  6. Från roten i databricks_jar_test mappen skapar du en JAR med namnet PrintArgs.jar:

    jar cvfm PrintArgs.jar META-INF/MANIFEST.MF *.class
    
  7. (Valfritt) Om du vill testa den kör du JAR från roten i databricks_jar_test mappen:

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

    Kommentar

    Om du får felet no main manifest attribute, in PrintArgs.jarmåste du lägga till en ny rad i slutet av MANIFEST.MF filen och sedan försöka skapa och köra JAR-filen igen.

  8. Ladda upp PrintArgs.jar till en volym. Se Ladda upp filer till en Unity Catalog-volym.

Skapa en Scala JAR

  1. Från mappen databricks_jar_test skapar du en tom fil med namnet build.sbt med följande innehåll:

    ThisBuild / scalaVersion := "2.12.14"
    ThisBuild / organization := "com.example"
    
    lazy val PrintArgs = (project in file("."))
      .settings(
        name := "PrintArgs"
      )
    
  2. Skapa mappstrukturen src/main/scala/examplefrån databricks_jar_test mappen .

  3. I mappen example skapar du en fil med namnet PrintArgs.scala med följande innehåll:

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

    sbt compile
    
  5. (Valfritt) Kör det kompilerade programmet:

    sbt "run Hello World\!"
    
    # Hello, World!
    
  6. I mappen databricks_jar_test/project skapar du en fil med namnet assembly.sbt med följande innehåll:

    addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0")
    
  7. Kör kommandot från mappens databricks_jar_testassembly rot, som genererar en JAR under mappen target :

    sbt assembly
    
  8. (Valfritt) Om du vill testa den kör du JAR från roten i databricks_jar_test mappen:

    java -jar target/scala-2.12/PrintArgs-assembly-0.1.0-SNAPSHOT.jar Hello World!
    
    # Hello, World!
    
  9. Ladda upp PrintArgs-assembly-0.1.0-SNAPSHOT.jar till en volym. Se Ladda upp filer till en Unity Catalog-volym.

Steg 3. Skapa ett Azure Databricks-jobb för att köra JAR

  1. Gå till din Azure Databricks-landningssida och gör något av följande:
    • I sidofältet klickar du på JobbikonArbetsflöden och klickar på Knappen Skapa jobb.
    • I sidofältet klickar du på Ny ikonNytt och väljer Jobb på menyn.
  2. I den aktivitetsdialogruta som visas på fliken Uppgifter ersätter du Lägg till ett namn för jobbet... med ditt jobbnamn, till exempel JAR example.
  3. Som Uppgiftsnamn anger du ett namn för aktiviteten, till exempel java_jar_task för Java eller scala_jar_task för Scala.
  4. För Typ väljer du JAR.
  5. För Main-klassen anger du PrintArgs i det här exemplet för Java eller example.PrintArgs Scala.
  6. För Kluster väljer du ett kompatibelt kluster. Se Stöd för Java- och Scala-bibliotek.
  7. För Beroende bibliotek klickar du på + Lägg till.
  8. I dialogrutan Lägg till beroende bibliotek, med Volymer markerat, anger du platsen där du laddade upp JAR -filen (PrintArgs.jar eller PrintArgs-assembly-0.1.0-SNAPSHOT.jar) i föregående steg till Volymfilsökväg, eller filtrerar eller bläddrar för att hitta JAR-filen. Välj den.
  9. Klicka på Lägg till.
  10. För Parametrar anger du ["Hello", "World!"]i det här exemplet .
  11. Klicka på Lägg till.

Steg 4: Kör jobbet och visa jobbkörningsinformationen

Klicka Knappen Kör nu för att köra arbetsflödet. Om du vill visa information om körningen klickar du på Visa körning i popup-fönstret Utlöst körning eller klickar på länken i kolumnen Starttid för körningen i jobbkörningsvyn.

När körningen är klar visas utdata i panelen Utdata , inklusive argumenten som skickas till uppgiften.

Storleksgränser för utdata för JAR-jobb

Jobbutdata, till exempel loggutdata som skickas till stdout, omfattas av en storleksgräns på 20 MB. Om totalutdata har en större storlek avbryts körningen och markeras som misslyckad.

För att undvika att stöta på den här gränsen kan du förhindra att stdout returneras från drivrutinen till Azure Databricks genom att ställa in Spark-konfigurationen spark.databricks.driver.disableScalaOutputtrue. Som standard är falseflaggvärdet . Flaggan styr cellutdata för Scala JAR-jobb och Scala-notebook-filer. Om flaggan är aktiverad returnerar Spark inte jobbkörningsresultat till klienten. Flaggan påverkar inte de data som skrivs i klustrets loggfiler. Databricks rekommenderar att du endast anger den här flaggan för jobbkluster för JAR-jobb eftersom den inaktiverar notebook-resultat.

Rekommendation: Använd den delade SparkContext

Eftersom Azure Databricks är en hanterad tjänst kan vissa kodändringar vara nödvändiga för att säkerställa att dina Apache Spark-jobb körs korrekt. JAR-jobbprogram måste använda det delade SparkContext API:et SparkContextför att hämta . Eftersom Azure Databricks initierar SparkContextkommer program som anropar new SparkContext() att misslyckas. För att hämta SparkContextanvänder du endast den delade SparkContext som skapats av Azure Databricks:

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

Det finns också flera metoder som du bör undvika när du använder den delade SparkContext.

  • Anropa SparkContext.stop()inte .
  • Anropa System.exit(0) inte eller sc.stop() i slutet av programmet Main . Detta kan orsaka odefinierat beteende.

Rekommendation: Använd try-finally block för jobbrensning

Tänk dig en JAR som består av två delar:

  • jobBody() som innehåller huvuddelen av jobbet.
  • jobCleanup() som måste köras efter jobBody(), oavsett om funktionen lyckades eller returnerade ett undantag.

Till exempel jobBody() skapar tabeller och jobCleanup() släpper dessa tabeller.

Det säkra sättet att se till att rensningsmetoden anropas är att placera ett try-finally block i koden:

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

Du bör inte försöka rensa med hjälp av sys.addShutdownHook(jobCleanup) eller följande kod:

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

På grund av hur Livslängden för Spark-containrar hanteras i Azure Databricks körs inte avstängningskrokerna på ett tillförlitligt sätt.

Konfigurera JAR-jobbparametrar

Du skickar parametrar till JAR-jobb med en JSON-strängmatris. Se objektet spark_jar_task i begärandetexten som skickades till åtgärden Skapa ett nytt jobb (POST /jobs/create) i JOBB-API:et. Om du vill komma åt dessa parametrar kontrollerar du matrisen som String skickats till din main funktion.

Hantera biblioteksberoenden

Spark-drivrutinen har vissa biblioteksberoenden som inte kan åsidosättas. Om ditt jobb lägger till bibliotek som är i konflikt har Beroenden för Spark-drivrutinsbiblioteket företräde.

Om du vill hämta den fullständiga listan över beroenden för drivrutinsbiblioteket kör du följande kommando i en notebook-fil som är kopplad till ett kluster som konfigurerats med samma Spark-version (eller klustret med den drivrutin som du vill undersöka):

%sh
ls /databricks/jars

När du definierar biblioteksberoenden för JAR:er rekommenderar Databricks att du listar Spark och Hadoop som provided beroenden. I Maven lägger du till Spark och Hadoop som tillhandahållna beroenden:

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

I sbtlägger du till Spark och Hadoop som tillhandahållna beroenden:

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

Dricks

Ange rätt Scala-version för dina beroenden baserat på vilken version du kör.

Nästa steg

Mer information om hur du skapar och kör Azure Databricks-jobb finns i Skapa och köra Azure Databricks-jobb.