Usare un file JAR in un processo di Azure Databricks
L'archivio Java o formato di file JAR si basa sul noto formato di file ZIP e viene usato per aggregare molti file Java o Scala in un unico file. Usando l'attività JAR, è possibile garantire un'installazione rapida e affidabile del codice Java o Scala nei processi di Azure Databricks. Questo articolo fornisce un esempio di creazione di un file JAR e di un processo che esegue l'applicazione in pacchetto nel file JAR. Nel seguente esempio, si eseguirà quanto segue:
- Creare il progetto JAR che definisce un'applicazione di esempio.
- Aggregare i file di esempio in un file JAR.
- Per eseguire il file JAR creare un processo.
- Eseguire il processo e visualizzare i risultati.
Prima di iniziare
Per completare questo esempio, è necessario quanto segue:
- Per Java JAR, Java Development Kit (JDK).
- Per i JAR Scala, JDK e sbt.
Passaggio 1: Creare una directory locale per l'esempio
Creare una directory locale per contenere il codice di esempio e gli artefatti generati, ad esempio databricks_jar_test
.
Passaggio 2: Creare il JAR
Completare le istruzioni seguenti per usare Java o Scala per creare il file JAR.
Creare un Java JAR
Nella cartella
databricks_jar_test
creare un file denominatoPrintArgs.java
con il seguente contenuto:import java.util.Arrays; public class PrintArgs { public static void main(String[] args) { System.out.println(Arrays.toString(args)); } }
Compilare il file
PrintArgs.java
, che crea il filePrintArgs.class
:javac PrintArgs.java
(Facoltativo) Eseguire il programma compilato:
java PrintArgs Hello World! # [Hello, World!]
Nella stessa cartella dei file
PrintArgs.java
ePrintArgs.class
creare una cartella denominataMETA-INF
.Nella cartella
META-INF
creare un file denominatoMANIFEST.MF
con il seguente contenuto. Assicurarsi di aggiungere una nuova riga alla fine di questo file:Main-Class: PrintArgs
Dalla radice della cartella
databricks_jar_test
creare un file JAR denominatoPrintArgs.jar
:jar cvfm PrintArgs.jar META-INF/MANIFEST.MF *.class
(Facoltativo) Per testarlo, dalla radice della cartella
databricks_jar_test
, eseguire il file JAR:java -jar PrintArgs.jar Hello World! # [Hello, World!]
Nota
In caso di get l'errore
no main manifest attribute, in PrintArgs.jar
, assicurati di aggiungere una nuova riga alla fine del fileMANIFEST.MF
e quindi prova a creare ed eseguire nuovamente il file JAR.Caricare
PrintArgs.jar
in un volume. Vedere Caricare file in un volume Catalog Unity.
Creare un file JAR Scala
Nella cartella
databricks_jar_test
creare un file vuoto denominatobuild.sbt
con il seguente contenuto:ThisBuild / scalaVersion := "2.12.14" ThisBuild / organization := "com.example" lazy val PrintArgs = (project in file(".")) .settings( name := "PrintArgs" )
databricks_jar_test
Dalla cartella creare la strutturasrc/main/scala/example
di cartelle .Nella cartella
example
creare un file denominatoPrintArgs.scala
con il seguente contenuto:package example object PrintArgs { def main(args: Array[String]): Unit = { println(args.mkString(", ")) } }
Compilare il programma:
sbt compile
(Facoltativo) Eseguire il programma compilato:
sbt "run Hello World\!" # Hello, World!
Nella cartella
databricks_jar_test/project
creare un file denominatoassembly.sbt
con il seguente contenuto:addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0")
Dalla radice della cartella
databricks_jar_test
eseguire il comandoassembly
, che genera un file JAR nella cartellatarget
:sbt assembly
(Facoltativo) Per testarlo, dalla radice della cartella
databricks_jar_test
, eseguire il file JAR:java -jar target/scala-2.12/PrintArgs-assembly-0.1.0-SNAPSHOT.jar Hello World! # Hello, World!
Caricare
PrintArgs-assembly-0.1.0-SNAPSHOT.jar
in un volume. Vedere Caricare file in un volume Catalog Unity.
Passaggio 3. Creare un processo di Azure Databricks per eseguire il file JAR
- Passare alla pagina di destinazione di Azure Databricks ed eseguire una delle operazioni seguenti:
- Nella barra laterale, fare clic su Flussi di lavoro e quindi .
- Nella barra laterale fare clic su Nuovo e select processo dal menu.
- Nella finestra di dialogo delle attività visualizzata nella scheda Attività sostituire Aggiungi un nome per il processo... con il nome del processo, ad esempio
JAR example
. - Per Nome attività immettere un nome per l'attività, ad esempio
java_jar_task
per Java oscala_jar_task
per Scala. - Per Tipo, selectJAR.
- Per Classe principale, per questo esempio, immettere
PrintArgs
per Java oexample.PrintArgs
per Scala. - Per il cluster , il cluster select è compatibile. Vedere Supporto per le librerie Java e Scala.
- Per Librerie dipendenti fare clic su + Aggiungi.
- Nella finestra di dialogo Aggiungi libreria dipendente, con Volumes selezionata, immettere il percorso where caricato il file JAR (
PrintArgs.jar
oPrintArgs-assembly-0.1.0-SNAPSHOT.jar
) nel passaggio precedente in Volumes Percorso fileo filtrare o cercare il file JAR. Select. - Fare clic su Aggiungi.
- Per Parameters, in questo esempio immettere
["Hello", "World!"]
. - Fare clic su Aggiungi.
Passaggio 4: Eseguire il processo e visualizzare i dettagli dell'esecuzione del processo
Fare clic su per eseguire il flusso di lavoro. Per visualizzare i dettagli
Al termine dell'esecuzione, l'output viene visualizzato nel pannello Output, inclusi gli argomenti passati all'attività.
Limiti delle dimensioni di output per i processi JAR
L'output del processo, ad esempio l'output del log generato in stdout, è soggetto a una dimensione di 20 MB limit. Se l'output totale ha dimensioni maggiori, l'esecuzione viene annullata e contrassegnata come non riuscita.
Per evitare di riscontrare questo limit, è possibile impedire che stdout venga restituito dal driver ad Azure Databricks impostando la configurazione di spark.databricks.driver.disableScalaOutput
Spark su true
. Per impostazione predefinita, il valore del flag è false
. Il flag controlla l'output della cella per i processi JAR scala e i notebook Scala. Se il flag è abilitato, Spark non restituisce i risultati dell'esecuzione del processo al client. Il flag non influisce sui dati scritti nei file di log del cluster. Databricks consiglia di impostare questo flag solo per i cluster automatizzati per i processi JAR, perché disabilita i risultati del notebook.
Raccomandazione: usare la condivisione SparkContext
Poiché Azure Databricks è un servizio gestito, potrebbero essere necessarie alcune modifiche al codice per garantire che i processi Apache Spark vengano eseguiti correttamente. I programmi di processo JAR devono usare l'API di SparkContext
condivisa per get il SparkContext
. Poiché Azure Databricks inizializza SparkContext
, i programmi che richiamano new SparkContext()
avranno esito negativo. Per get il SparkContext
, usare solo i SparkContext
condivisi creati da Azure Databricks:
val goodSparkContext = SparkContext.getOrCreate()
val goodSparkSession = SparkSession.builder().getOrCreate()
Esistono anche diversi metodi da evitare quando si usa l'oggetto condiviso SparkContext
.
- Non chiamare
SparkContext.stop()
. - Non chiamare
System.exit(0)
osc.stop()
alla fine del programmaMain
. Ciò potrebbe causare comportamenti inaspettati.
Raccomandazione: usare i blocchi try-finally
per la pulizia del processo
Si consideri un file JAR costituito da due parti:
-
jobBody()
che contiene la parte principale del processo. -
jobCleanup()
che deve essere eseguito dopojobBody()
, indipendentemente dal fatto che tale funzione abbia avuto esito positivo o restituito un'eccezione.
Ad esempio, jobBody()
crea tables e jobCleanup()
elimina tali tables.
Il modo sicuro per assicurarsi che venga chiamato il metodo di pulizia consiste nell'inserire un blocco try-finally
nel codice:
try {
jobBody()
} finally {
jobCleanup()
}
Non è consigliabile provare a eseguire la pulizia usando sys.addShutdownHook(jobCleanup)
o il codice seguente:
val cleanupThread = new Thread { override def run = jobCleanup() }
Runtime.getRuntime.addShutdownHook(cleanupThread)
A causa del modo in cui la durata dei contenitori Spark viene gestita in Azure Databricks, gli hook di arresto non vengono eseguiti in modo affidabile.
Configurazione del processo JAR parameters
Passare parameters ai processi JAR con una matrice di stringhe JSON. Vedere l'oggetto spark_jar_task
nel corpo della richiesta passato all'operazione Crea un nuovo processo (POST /jobs/create
) nell'API Processi. Per accedere a questi parameters, esaminare l'array String
passato nella funzione main
.
Gestione delle dipendenze della libreria
Il driver Spark presenta alcune dipendenze della libreria che non possono essere sottoposte a override. Se il processo aggiunge librerie in conflitto, le dipendenze della libreria del driver Spark hanno la precedenza.
Per get il list completo delle dipendenze della libreria driver, eseguire il comando seguente in un notebook collegato a un cluster configurato con la stessa versione di Spark (o il cluster con il driver da esaminare):
%sh
ls /databricks/jars
Quando si definiscono le dipendenze della libreria per i file JAR, Databricks consiglia di elencare Spark e Hadoop come provided
dipendenze. In Maven aggiungere Spark e Hadoop come dipendenze fornite:
<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>
In sbt
aggiungere Spark e Hadoop come dipendenze fornite:
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.3.0" % "provided"
libraryDependencies += "org.apache.hadoop" %% "hadoop-core" % "1.2.1" % "provided"
Suggerimento
Specificare la versione di Scala corretta per le dipendenze in base alla versione in esecuzione.
Passaggi successivi
Per altre informazioni sulla creazione e l'esecuzione di processi di Azure Databricks, vedere Pianificare e orchestrare i flussi di lavoro.