Delen via


Een JAR gebruiken in een Azure Databricks-taak

Het Java-archief of [JAR](https://en.wikipedia.org/wiki/JAR_(file_format) bestandsindeling is gebaseerd op de populaire ZIP-bestandsindeling en wordt gebruikt voor het samenvoegen van veel Java- of Scala-bestanden in één. Met behulp van de JAR-taak kunt u snelle en betrouwbare installatie van Java- of Scala-code in uw Azure Databricks-taken garanderen. Dit artikel bevat een voorbeeld van het maken van een JAR en een taak waarmee de toepassing wordt uitgevoerd die is verpakt in de JAR. In dit voorbeeld gaat u het volgende doen:

  • Maak het JAR-project waarin een voorbeeldtoepassing wordt gedefinieerd.
  • Bundel de voorbeeldbestanden in een JAR.
  • Maak een taak om het JAR-bestand uit te voeren.
  • Voer de taak uit en bekijk de resultaten.

Voordat u begint

U hebt het volgende nodig om dit voorbeeld te voltooien:

  • Voor Java JAR's, de Java Development Kit (JDK).
  • Voor Scala-JA's, de JDK en sbt.

Stap 1: Een lokale map maken voor het voorbeeld

Maak een lokale map voor het opslaan van de voorbeeldcode en gegenereerde artefacten, databricks_jar_testbijvoorbeeld.

Stap 2: het JAR-bestand maken

Volg de volgende instructies om Java of Scala te gebruiken om het JAR-bestand te maken.

Een Java JAR maken

  1. Maak vanuit de databricks_jar_test map een bestand met de naam PrintArgs.java met de volgende inhoud:

    import java.util.Arrays;
    
    public class PrintArgs {
      public static void main(String[] args) {
        System.out.println(Arrays.toString(args));
      }
    }
    
  2. Compileer het PrintArgs.java bestand, waarmee het bestand PrintArgs.classwordt gemaakt:

    javac PrintArgs.java
    
  3. (Optioneel) Voer het gecompileerde programma uit:

    java PrintArgs Hello World!
    
    # [Hello, World!]
    
  4. Maak in dezelfde map als de en PrintArgs.class bestanden een map met de PrintArgs.java naam META-INF.

  5. Maak in de META-INF map een bestand met de naam MANIFEST.MF met de volgende inhoud. Zorg ervoor dat u een nieuwe regel toevoegt aan het einde van dit bestand:

    Main-Class: PrintArgs
    
  6. Maak vanuit de hoofdmap van de map een JAR met de databricks_jar_test naam PrintArgs.jar:

    jar cvfm PrintArgs.jar META-INF/MANIFEST.MF *.class
    
  7. (Optioneel) Als u dit wilt testen, voert u vanuit de hoofdmap van de databricks_jar_test map het JAR-bestand uit:

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

    Notitie

    Als u de fout no main manifest attribute, in PrintArgs.jarkrijgt, voegt u een nieuwe regel toe aan het einde van het MANIFEST.MF bestand en probeert u het JAR-bestand opnieuw te maken en uit te voeren.

  8. Uploaden PrintArgs.jar naar een volume. Zie Bestanden uploaden naar een Unity Catalog-volume.

Een Scala JAR maken

  1. Maak vanuit de databricks_jar_test map een leeg bestand met de naam build.sbt met de volgende inhoud:

    ThisBuild / scalaVersion := "2.12.14"
    ThisBuild / organization := "com.example"
    
    lazy val PrintArgs = (project in file("."))
      .settings(
        name := "PrintArgs"
      )
    
  2. Maak vanuit de databricks_jar_test map de mapstructuur src/main/scala/example.

  3. Maak in de example map een bestand met de naam PrintArgs.scala met de volgende inhoud:

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

    sbt compile
    
  5. (Optioneel) Voer het gecompileerde programma uit:

    sbt "run Hello World\!"
    
    # Hello, World!
    
  6. Maak in de databricks_jar_test/project map een bestand met de naam assembly.sbt met de volgende inhoud:

    addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0")
    
  7. Voer vanuit de hoofdmap van de databricks_jar_test map de assembly opdracht uit, waarmee een JAR wordt gegenereerd onder de target map:

    sbt assembly
    
  8. (Optioneel) Als u dit wilt testen, voert u vanuit de hoofdmap van de databricks_jar_test map het JAR-bestand uit:

    java -jar target/scala-2.12/PrintArgs-assembly-0.1.0-SNAPSHOT.jar Hello World!
    
    # Hello, World!
    
  9. Uploaden PrintArgs-assembly-0.1.0-SNAPSHOT.jar naar een volume. Zie Bestanden uploaden naar een Unity Catalog-volume.

Stap 3. Een Azure Databricks-taak maken om het JAR-bestand uit te voeren

  1. Ga naar de landingspagina van Azure Databricks en voer een van de volgende handelingen uit:
    • Klik in de zijbalk op Pictogram Werkstromen Werkstromen en klik op Knop Taak maken.
    • Klik in de zijbalk op Nieuw pictogram Nieuw en selecteer Taak in het menu.
  2. Vervang in het taakdialoogvenster dat wordt weergegeven op het tabblad Taken een naam voor uw taak toevoegen... door de naam van uw taak, bijvoorbeeldJAR example.
  3. Voer voor taaknaam een naam in voor de taak, bijvoorbeeld java_jar_task voor Java of scala_jar_task scala.
  4. Selecteer JAR voor Type.
  5. Voer voor Main-klasse voor dit voorbeeld in PrintArgs voor Java of example.PrintArgs voor Scala.
  6. Selecteer voor Cluster een compatibel cluster. Zie ondersteuning voor Java- en Scala-bibliotheken.
  7. Klik op + Toevoegen voor afhankelijke bibliotheken.
  8. Voer in het dialoogvenster Afhankelijke bibliotheek toevoegen, met Volumes geselecteerd, de locatie in waar u de JAR (PrintArgs.jar of PrintArgs-assembly-0.1.0-SNAPSHOT.jar) in de vorige stap hebt geüpload naar het bestandspad van volumes, of filter of blader om het JAR-bestand te zoeken. Selecteer het.
  9. Klik op Toevoegen.
  10. Voer ["Hello", "World!"]voor Parameters voor dit voorbeeld .
  11. Klik op Toevoegen.

Stap 4: Voer de taak uit en bekijk de details van de taakuitvoering

Klik Knop Nu uitvoeren hier om de werkstroom uit te voeren. Als u details voor de uitvoering wilt weergeven, klikt u op Uitvoering weergeven in het pop-upvenster Geactiveerde uitvoering of klikt u op de koppeling in de kolom Begintijd voor de uitvoering in de weergave taakuitvoeringen.

Wanneer de uitvoering is voltooid, wordt de uitvoer weergegeven in het deelvenster Uitvoer , inclusief de argumenten die aan de taak zijn doorgegeven.

Uitvoergroottelimieten voor JAR-taken

Taakuitvoer, zoals logboekuitvoer die naar stdout wordt verzonden, is onderworpen aan een maximale grootte van 20 MB. Als de totale uitvoer een grotere grootte heeft, wordt de uitvoering geannuleerd en gemarkeerd als mislukt.

Om te voorkomen dat deze limiet wordt bereikt, kunt u voorkomen dat stdout wordt geretourneerd van het stuurprogramma naar Azure Databricks door de spark.databricks.driver.disableScalaOutput Spark-configuratie in te stellen op true. Standaard is falsede vlagwaarde . De vlag bepaalt de celuitvoer voor Scala JAR-taken en Scala-notebooks. Als de vlag is ingeschakeld, retourneert Spark geen taakuitvoeringsresultaten naar de client. De vlag heeft geen invloed op de gegevens die zijn geschreven in de logboekbestanden van het cluster. Databricks raadt aan deze vlag alleen in te stellen voor taakclusters voor JAR-taken, omdat hiermee notebookresultaten worden uitgeschakeld.

Aanbeveling: Het gedeelde gebruiken SparkContext

Omdat Azure Databricks een beheerde service is, zijn er mogelijk enkele codewijzigingen nodig om ervoor te zorgen dat uw Apache Spark-taken correct worden uitgevoerd. JAR-taakprogramma's moeten de gedeelde SparkContext API gebruiken om de SparkContext. Omdat Azure Databricks de SparkContextinitialiseert, mislukken programma's die worden aangeroepen new SparkContext() . Gebruik alleen de gedeelde SparkContext gegevens die zijn gemaakt door Azure Databricks om de SparkContextopdracht op te halen:

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

Er zijn ook verschillende methoden die u moet vermijden wanneer u de gedeelde methode gebruikt SparkContext.

  • Bel niet SparkContext.stop().
  • Bel of sc.stop() aan het einde van uw Main programma nietSystem.exit(0). Dit kan niet-gedefinieerd gedrag veroorzaken.

Aanbeveling: Blokken gebruiken try-finally voor het opschonen van taken

Overweeg een JAR die uit twee delen bestaat:

  • jobBody() dat het belangrijkste deel van de taak bevat.
  • jobCleanup() die moet worden uitgevoerd na jobBody(), of die functie is geslaagd of een uitzondering heeft geretourneerd.

Hiermee maakt u bijvoorbeeld jobBody() tabellen en jobCleanup() verwijdert u deze tabellen.

De veilige manier om ervoor te zorgen dat de opschoonmethode wordt aangeroepen, is door een try-finally blok in de code te plaatsen:

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

Probeer niet op te schonen met behulp van sys.addShutdownHook(jobCleanup) of de volgende code:

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

Vanwege de manier waarop de levensduur van Spark-containers wordt beheerd in Azure Databricks, worden de afsluithaken niet betrouwbaar uitgevoerd.

JAR-taakparameters configureren

U geeft parameters door aan JAR-taken met een JSON-tekenreeksmatrix. Zie het spark_jar_task object in de aanvraagbody die is doorgegeven aan de taakbewerking Maken (POST /jobs/create) in de Taken-API. Voor toegang tot deze parameters inspecteert u de String matrix die is doorgegeven aan uw main functie.

Bibliotheekafhankelijkheden beheren

Het Spark-stuurprogramma heeft bepaalde bibliotheekafhankelijkheden die niet kunnen worden overschreven. Als uw taak conflicterende bibliotheken toevoegt, hebben de afhankelijkheden van de Spark-stuurprogrammabibliotheek voorrang.

Als u de volledige lijst met de afhankelijkheden van de stuurprogrammabibliotheek wilt ophalen, voert u de volgende opdracht uit in een notebook dat is gekoppeld aan een cluster dat is geconfigureerd met dezelfde Spark-versie (of het cluster met het stuurprogramma dat u wilt onderzoeken):

%sh
ls /databricks/jars

Wanneer u bibliotheekafhankelijkheden voor JAR's definieert, raadt Databricks aan Spark en Hadoop als afhankelijkheden weer provided te geven. Voeg in Maven Spark en Hadoop toe als opgegeven afhankelijkheden:

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

Voeg sbtSpark en Hadoop toe als opgegeven afhankelijkheden:

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

Tip

Geef de juiste Scala-versie op voor uw afhankelijkheden op basis van de versie die u uitvoert.

Volgende stappen

Zie Werkstromen plannen en organiseren voor meer informatie over het maken en uitvoeren van Azure Databricks-taken.