Pular para o conteúdo principal

Use um JAR em um Databricks Job

O formato de arquivo Java ou JAR é baseado no popular formato de arquivo ZIP e é usado para agregar muitos arquivos Java ou Scala em um só. Usando a tarefa JAR, o senhor pode garantir a instalação rápida e confiável do código Java ou Scala no seu trabalho Databricks. Este artigo fornece um exemplo de criação de um JAR e um Job que executa o pacote de aplicativos no JAR. Neste exemplo, você vai:

  • Crie o projeto JAR que define um aplicativo de exemplo.
  • Agrupe os arquivos de exemplo em um JAR.
  • Criar um Job para executar o JAR.
  • Execute o job e veja os resultados.

Antes de começar

Você precisa do seguinte para concluir este exemplo:

  • Para JARs Java, o Java Development Kit (JDK).
  • Para JARs do Scala, o JDK e o sbt.

Etapa 1: criar um diretório local para o exemplo

Crie um diretório local para armazenar o código de exemplo e os artefatos gerados, por exemplo, databricks_jar_test.

Etapa 2: Criar o JAR

Siga as instruções a seguir para usar Java ou Scala para criar o JAR.

Criar um Java JAR

  1. Na pasta databricks_jar_test, crie um arquivo chamado PrintArgs.java com o seguinte conteúdo:

    Java
    import java.util.Arrays;

    public class PrintArgs {
    public static void main(String[] args) {
    System.out.println(Arrays.toString(args));
    }
    }
  2. Compile o arquivo PrintArgs.java, que cria o arquivo PrintArgs.class:

    Bash
    javac PrintArgs.java
  3. (Opcional) executar o programa compilado:

    Bash
    java PrintArgs Hello World!

    # [Hello, World!]
  4. Na mesma pasta dos arquivos PrintArgs.java e PrintArgs.class, crie uma pasta chamada META-INF.

  5. Na pasta META-INF, crie um arquivo chamado MANIFEST.MF com o seguinte conteúdo. Certifique-se de adicionar uma nova linha no final deste arquivo:

    Main-Class: PrintArgs
  6. Na raiz da pasta databricks_jar_test, crie um JAR chamado PrintArgs.jar:

    Bash
    jar cvfm PrintArgs.jar META-INF/MANIFEST.MF *.class
  7. (Opcional) Para testá-lo, na raiz da pasta databricks_jar_test, execute o endereço JAR:

    Bash
    java -jar PrintArgs.jar Hello World!

    # [Hello, World!]
nota

Se o senhor receber o erro no main manifest attribute, in PrintArgs.jar, certifique-se de adicionar uma nova linha ao final do arquivo MANIFEST.MF e, em seguida, tente criar e executar o JAR novamente.

  1. Faça o upload de PrintArgs.jar para um volume. Consulte Fazer upload de arquivos para um volume do Unity Catalog.

Criar um JAR do Scala

  1. Na pasta databricks_jar_test, crie um arquivo vazio chamado build.sbt com o seguinte conteúdo:

    ThisBuild / scalaVersion := "2.12.14"
    ThisBuild / organization := "com.example"

    lazy val PrintArgs = (project in file("."))
    .settings(
    name := "PrintArgs"
    )
  2. Na pasta databricks_jar_test, crie a estrutura de pastas src/main/scala/example.

  3. Na pasta example, crie um arquivo chamado PrintArgs.scala com o seguinte conteúdo:

    Scala
    package example

    object PrintArgs {
    def main(args: Array[String]): Unit = {
    println(args.mkString(", "))
    }
    }
  4. Compile o programa:

    Bash
    sbt compile
  5. (Opcional) executar o programa compilado:

    Bash
    sbt "run Hello World\!"

    # Hello, World!
  6. Na pasta databricks_jar_test/project, crie um arquivo chamado assembly.sbt com o seguinte conteúdo:

    addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.0.0")
  7. Na raiz da pasta databricks_jar_test, execute o comando assembly, que gera um JAR na pasta target:

    Bash
    sbt assembly
  8. (Opcional) Para testá-lo, na raiz da pasta databricks_jar_test, execute o endereço JAR:

    Bash
    java -jar target/scala-2.12/PrintArgs-assembly-0.1.0-SNAPSHOT.jar Hello World!

    # Hello, World!
  9. Faça o upload de PrintArgs-assembly-0.1.0-SNAPSHOT.jar para um volume. Consulte Fazer upload de arquivos para um volume do Unity Catalog.

Etapa 3. Crie um Databricks Job para executar o JAR

  1. Acesse o site Databricks páginas de aterrissagem e faça uma das seguintes ações:

    • Na barra lateral, clique em fluxo de trabalho Icon fluxo de trabalho e clique em Botão criar job.
    • Na barra lateral, clique em Novo ícone New e selecione Job no menu.
  2. Na caixa de diálogo da tarefa que aparece na tarefa tab, substitua Add a name for your Job (Adicionar um nome para o trabalho ) pelo nome do trabalho, por exemplo, JAR example.

  3. Para o nome da tarefa , digite um nome para a tarefa, por exemplo, java_jar_task para Java, ou scala_jar_task para Scala.

  4. Para Type , selecione JAR .

  5. Para a classe Main , neste exemplo, digite PrintArgs para Java ou example.PrintArgs para Scala.

  6. Para o clustering , selecione um clustering compatível. Consulte Java e Scala para obter suporte à biblioteca.

  7. Para Biblioteca dependente , clique em + Adicionar .

  8. Na caixa de diálogo Add dependent library (Adicionar biblioteca dependente ), com Volumes (Volumes ) selecionado, insira o local onde o senhor carregou o JAR (PrintArgs.jar ou PrintArgs-assembly-0.1.0-SNAPSHOT.jar) na etapa anterior em Volumes File Path (Caminho do arquivo de volumes ), ou filtre ou navegue para localizar o JAR. Selecione-o.

  9. Clique em Adicionar .

  10. Em Parâmetros , neste exemplo, digite ["Hello", "World!"].

  11. Clique em Adicionar .

Etapa 4: executar o trabalho e view os detalhes da execução do trabalho

Clique em Botão executar agora para executar o fluxo de trabalho. Para acessar view detalhes da execução, clique em view execution (visualizar execução ) na janela pop-up Triggered execution (execução acionada ) ou clique no link na coluna começar time (tempo ) para a execução no Job execution (execução de trabalho) view.

Quando a execução for concluída, a saída será exibida no painel Output (Saída ), incluindo os argumentos passados para a tarefa.

Limites de tamanho de saída para JAR Job

Job A saída, como a saída log emitida para stdout, está sujeita a um limite de tamanho de 20 MB. Se a saída total tiver um tamanho maior, a execução será cancelada e marcada como falha.

Para evitar esse limite, o senhor pode impedir que o stdout seja retornado do driver para a Databricks definindo a configuração spark.databricks.driver.disableScalaOutput Spark como true. Em default, o valor do sinalizador é false. O sinalizador controla a saída de células para Scala JAR Job e Scala Notebook. Se o sinalizador estiver ativado, o site Spark não retornará os resultados da execução do trabalho para o cliente. O sinalizador não afeta os dados que são gravados nos arquivos log do clustering. Databricks recomenda definir esse sinalizador somente para o agrupamento de trabalhos para o JAR Job porque ele desativa os resultados do Notebook.

Recomendação: use o compartilhado SparkContext

Como o Databricks é um serviço gerenciado, talvez sejam necessárias algumas alterações no código para garantir que o Apache Spark Job seja executado corretamente. JAR Os programas de trabalho devem usar o SparkContext compartilhado API para obter o SparkContext. Como o Databricks inicializa o SparkContext, os programas que invocam o new SparkContext() falharão. Para obter o SparkContext, use apenas o SparkContext compartilhado criado pela Databricks:

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

Há também vários métodos que você deve evitar ao usar o SparkContext compartilhado.

  • Não ligue para SparkContext.stop().
  • Não ligue para System.exit(0) ou sc.stop() no final do seu programa Main. Isso pode causar um comportamento indefinido.

Recomendação: Use o site try-finally blocks para a limpeza do trabalho

Considere um JAR que consiste em duas partes:

  • jobBody() que contém a parte principal do trabalho.
  • jobCleanup() que deve ser executado após jobBody(), independentemente de a função ter sido bem-sucedida ou ter retornado uma exceção.

Por exemplo, jobBody() cria tabelas e jobCleanup() descarta essas tabelas.

A maneira segura de garantir que o método de limpeza seja chamado é colocar um bloco try-finally no código:

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

Você não deve tentar limpar usando sys.addShutdownHook(jobCleanup) ou o seguinte código:

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

Devido à forma como o tempo de vida dos contêineres Spark é gerenciado em Databricks, os ganchos de desligamento não são executados de forma confiável.

Configuração dos parâmetros do trabalho JAR

O senhor passa parâmetros para JAR Job com uma matriz de strings JSON. Veja o objeto spark_jar_task no corpo da solicitação passado para as operações Create a new Job (POST /jobs/create) em Jobs API. Para acessar esses parâmetros, inspecione a matriz String passada para sua função main.

gerenciar dependências da biblioteca

O driver do Spark tem certas dependências de biblioteca que não podem ser substituídas. Se o seu trabalho adicionar uma biblioteca conflitante, as dependências da biblioteca do driver Spark terão precedência.

Para obter a lista completa das dependências do driver da biblioteca, execute o seguinte comando em um Notebook anexado a um cluster configurado com a mesma versão do Spark (ou o cluster com o driver que o senhor deseja examinar):

Bash
%sh
ls /databricks/jars

Quando o senhor define dependências de biblioteca para JARs, a Databricks recomenda listar o Spark e o Hadoop como provided dependências. No Maven, adicione o Spark e o Hadoop como dependências fornecidas:

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

Em sbt, adicione o Spark e o Hadoop como dependências fornecidas:

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

Especifique a versão correta do Scala para suas dependências com base na versão que está sendo executada.

Próximas etapas

Para saber mais sobre como criar e executar o Databricks Job, consulte orquestração usando o Databricks Jobs.