Usar um JAR em um trabalho do Azure Databricks

O arquivo Java ou [JAR](https://en.wikipedia.org/wiki/JAR_(file_format) formato de arquivo é baseado no popular formato de arquivo ZIP e é usado para agregar muitos arquivos Java ou Scala em um. Usando a tarefa JAR, você pode garantir a instalação rápida e confiável do código Java ou Scala em seus trabalhos do Azure Databricks. Este artigo fornece um exemplo de criação de um JAR e um trabalho que executa o aplicativo empacotado no JAR. Neste exemplo, você irá:

  • Crie o projeto JAR definindo um aplicativo de exemplo.
  • Agrupe os arquivos de exemplo em um JAR.
  • Crie um trabalho para executar o JAR.
  • Execute o trabalho e visualize os resultados.

Antes de começar

Você precisa do seguinte para concluir este exemplo:

  • Para Java JARs, o Java Development Kit (JDK).
  • Para JARs 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

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

Criar um Java JAR

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

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

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

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

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

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

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

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

    Nota

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

  8. Carregue PrintArgs.jar para um volume. Consulte Carregar arquivos para um volume do Catálogo Unity.

Criar um JAR Scala

  1. databricks_jar_test Na pasta, crie um arquivo vazio nomeado 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. A partir da pasta, crie a databricks_jar_test estrutura src/main/scala/examplede pastas .

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

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

    sbt compile
    
  5. (Opcional) Execute o programa compilado:

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

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

    sbt assembly
    
  8. (Opcional) Para testá-lo, a partir da raiz da pasta, execute o databricks_jar_test JAR:

    java -jar target/scala-2.12/PrintArgs-assembly-0.1.0-SNAPSHOT.jar Hello World!
    
    # Hello, World!
    
  9. Carregue PrintArgs-assembly-0.1.0-SNAPSHOT.jar para um volume. Consulte Carregar arquivos para um volume do Catálogo Unity.

Passo 3. Criar um trabalho do Azure Databricks para executar o JAR

  1. Vá para a página inicial do Azure Databricks e siga um destes procedimentos:
    • Na barra lateral, clique em Ícone Fluxos de Trabalho Fluxos de trabalho e clique em Botão Criar Trabalho.
    • Na barra lateral, clique em Novo ícone Novo e selecione Trabalho no menu.
  2. Na caixa de diálogo de tarefa que aparece na guia Tarefas, substitua Adicionar um nome para o trabalho... pelo nome do trabalho, por exemploJAR example.
  3. Em Nome da tarefa, insira um nome para a tarefa, por exemplo java_jar_task , para Java ou scala_jar_task para Scala.
  4. Em Tipo, selecione JAR.
  5. Para Classe Principal, para este exemplo, insira PrintArgs Java ou example.PrintArgs Scala.
  6. Em Cluster, selecione um cluster compatível. Consulte Suporte a bibliotecas Java e Scala.
  7. Para Bibliotecas dependentes, clique em + Adicionar.
  8. Na caixa de diálogo Adicionar biblioteca dependente, com Volumes selecionados, insira o local onde você carregou o JAR (PrintArgs.jar ou PrintArgs-assembly-0.1.0-SNAPSHOT.jar) na etapa anterior em Caminho do Arquivo de Volumes, ou filtre ou navegue para localizar o JAR. Selecione-a.
  9. Clique em Adicionar.
  10. Em Parâmetros, para este exemplo, insira ["Hello", "World!"].
  11. Clique em Adicionar.

Etapa 4: Executar o trabalho e exibir os detalhes da execução do trabalho

Clique Botão Executar agora para executar o fluxo de trabalho. Para exibir detalhes da execução, clique em Exibir execução no pop-up Execução acionada ou clique no link na coluna Hora de início da execução na exibição de execução do trabalho.

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

Limites de tamanho de saída para trabalhos JAR

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

Para evitar encontrar esse limite, você pode impedir que o stdout seja retornado do driver para o Azure Databricks definindo a configuração do spark.databricks.driver.disableScalaOutput Spark como true. Por padrão, o valor do sinalizador é false. O sinalizador controla a saída da célula para trabalhos JAR Scala e notebooks Scala. Se o sinalizador estiver habilitado, o Spark não retornará os resultados da execução do trabalho para o cliente. O sinalizador não afeta os dados gravados nos arquivos de log do cluster. O Databricks recomenda definir esse sinalizador apenas para clusters de tarefas para trabalhos JAR porque ele desabilita os resultados do bloco de anotações.

Recomendação: Use o SparkContext

Como o Azure Databricks é um serviço gerenciado, algumas alterações de código podem ser necessárias para garantir que seus trabalhos do Apache Spark sejam executados corretamente. Os programas de trabalho JAR devem usar a API compartilhada SparkContext para obter o SparkContext. Como o Azure Databricks inicializa o , os SparkContextprogramas que invocarem new SparkContext() falharão. Para obter o SparkContext, use apenas o compartilhado SparkContext criado pelo Azure Databricks:

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

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

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

Recomendação: Use try-finally blocos para limpeza de trabalhos

Considere um JAR que consiste em duas partes:

  • jobBody() que contém a parte principal do trabalho.
  • jobCleanup() que tem de ser executada após jobBody(), quer essa função tenha sido bem-sucedida ou devolvida a 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 try-finally bloco no código:

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

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

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

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

Configurando parâmetros de trabalho JAR

Você passa parâmetros para trabalhos JAR com uma matriz de cadeia de caracteres JSON. Veja o spark_jar_task objeto no corpo da solicitação passado para a operação Criar um novo trabalho (POST /jobs/create) na API de Trabalhos. Para acessar esses parâmetros, inspecione a String matriz passada para sua main função.

Gerenciar dependências de bibliotecas

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

Para obter a lista completa das dependências da biblioteca de drivers, execute o seguinte comando em um bloco de anotações conectado a um cluster configurado com a mesma versão do Spark (ou o cluster com o driver que você deseja examinar):

%sh
ls /databricks/jars

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

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

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

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

Gorjeta

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

Passos seguintes

Para saber mais sobre como criar e executar trabalhos do Azure Databricks, consulte Criar e executar trabalhos do Azure Databricks.