Escreva e execute jobs do Spark Scala no Cloud Dataproc

Este tutorial ilustra maneiras diferentes de criar e enviar um job do Spark Scala a um cluster do Cloud Dataproc, incluindo:

  • gravar e compilar um aplicativo “Hello World” do Spark Scala em uma máquina local a partir da linha de comando usando o Scala REPL (Read-Evaluate-Print-Loop ou intérprete interativo), a ferramenta de compilação SBT ou o Eclipse IDE usando o plug-in Scala IDE para Eclipse
  • empacotar classes do Scala compiladas em um arquivo jar com um manifesto;
  • enviar o jar do Scala a um job Spark que seja executado no cluster do Cloud Dataproc;
  • examinar o resultado do job do Scala no Console do Google Cloud.

Este tutorial também mostra como:

  • gravar e executar um job mapreduce "WordCount'" do Spark Scala diretamente em um cluster do Cloud Dataproc usando o REPL spark-shell;

  • executar exemplos pré-instalados do Apache Spark e do Hadoop em um cluster.

Configure um projeto do Google Cloud Platform

Faça o seguinte, se ainda não tiver feito:

  1. Configure um projeto.
  2. Crie um intervalo do Cloud Storage.
  3. Crie um cluster do Cloud Dataproc.

Escrever e compilar código em Scala localmente

Como um exercício simples para este tutorial, escreva um aplicativo "Hello World" em Scala usando o Scala REPL, a interface de linha de comando SBT ou o plug-in Scala IDE para Eclipse localmente na máquina de desenvolvimento.

Como usar o Scala

  1. Faça download dos binários do Scala na página de instalação do Scala.
  2. Desempacote o arquivo, defina a variável de ambiente SCALA_HOME e adicione-a ao caminho, conforme mostrado nas instruções de instalação do Scala. Exemplo:

        export SCALA_HOME=/usr/local/share/scala
        export PATH=$PATH:$SCALA_HOME/
        

  3. Inicie o Scala REPL.

        $ scala
        Welcome to Scala version ...
        Type in expressions to have them evaluated.
        Type :help for more information.
        scala>
        

  4. Copie e cole o código HelloWorld no Scala REPL.

        object HelloWorld {
          def main(args: Array[String]): Unit = {
            println("Hello, world!")
          }
        }
    
        

  5. Salve HelloWorld.scala e saia do REPL.

        scala> :save HelloWorld.scala
        scala> :q
        

  6. Compile com scalac.

        $ scalac HelloWorld.scala
        

  7. Liste os arquivos .class compilados.

        $ ls HelloWorld*.class
        HelloWorld$.class   HelloWorld.class
        

Como usar o SBT

  1. Faça o download do SBT.

  2. Crie um projeto "HelloWorld", como mostrado abaixo.

        $ mkdir hello
        $ cd hello
        $ echo \
        'object HelloWorld {def main(args: Array[String]) = println("Hello, world!")}' > \
        HelloWorld.scala
        

  3. Crie um arquivo de configuração sbt.build para definir o artifactName (o nome do arquivo jar que você irá gerar abaixo) como "HelloWorld.jar" (consulte Como modificar os artefatos padrão).

        echo \
        'artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
        "HelloWorld.jar" }' > \
        build.sbt
        

  4. Inicie o SBT e execute o código.

        $ sbt
        [info] Set current project to hello ...
        > run
        ... Compiling 1 Scala source to .../hello/target/scala-.../classes...
        ... Running HelloWorld
        Hello, world!
        [success] Total time: 3 s ...
        

  5. Empacote o código em um arquivo jar com um manifesto que especifique o ponto de entrada de classe principal (HelloWorld) e depois saia.

        > package
        ... Packaging .../hello/target/scala-.../HelloWorld.jar ...
        ... Done packaging.
        [success] Total time: ...
        > exit
        

Como usar o plug-in SBT para Eclipse

  1. Instale o plug-in SBT para Eclipse.

  2. Selecione/crie um espaço de trabalho e inicie um novo projeto do Scala.

  3. Na página Create a Scala project, nomeie o projeto "HelloWorld" e clique em Finish para aceitar as configurações padrão.

  4. Selecione a pasta src no painel esquerdo (Package Explorer) e selecione New→Scala Object.

  5. Insira "HelloWorld" como sendo o nome do objeto do Scala na caixa de diálogo Create New File e clique em Finish.

  6. O arquivo HelloWorld.scala é criado com um modelo de objeto HelloWorld. Preencha o modelo para concluir a definição do objeto HelloWorld da seguinte maneira:

        object HelloWorld {
          def main(args: Array[String]): Unit = {
            println("Hello, world!")
          }
        }
    
        

  7. Clique no documento HelloWorld.scala ou selecione o nome do documento no painel esquerdo (Package Explorer). Em seguida, clique com o botão direito do mouse e selecione Run As→Scala Application para criar e executar o aplicativo.

  8. O console mostra que o aplicativo foi criado e executado com sucesso.

  9. Os arquivos de classe compilados estão localizados na pasta bin do projeto no espaço de trabalho do Eclipse. Use esses arquivos para criar um jar (consulte Criar um jar).

Criar um jar

Crie um arquivo jar com SBT ou usando o comando jar.

Como usar o SBT

O comando de pacote do SBT cria um arquivo jar (consulte Como usar o SBT.

Criação manual do jar

  1. Altere o diretório (cd) no diretório que contém os arquivos HelloWorld*.class compilados e execute o seguinte comando para empacotar os arquivos de classe em um jar com um manifesto que especifique o ponto de entrada de classe principal (HelloWorld).
        $ jar cvfe HelloWorld.jar HelloWorld HelloWorld*.class
        added manifest
        adding: HelloWorld$.class(in = 637) (out= 403)(deflated 36%)
        adding: HelloWorld.class(in = 586) (out= 482)(deflated 17%)
        

Copiar o jar no Cloud Storage

  1. Use o comando gsutil para copiar o jar para um intervalo do Cloud Storage do projeto.
    $ gsutil cp HelloWorld.jar gs://<bucket-name>/
    Copying file://HelloWorld.jar [Content-Type=application/java-archive]...
    Uploading   gs://bucket-name/HelloWorld.jar:         1.46 KiB/1.46 KiB
    

Enviar o jar a um job Spark do Cloud Dataproc

  1. Use o Console do Cloud para enviar o arquivo jar para o job Spark do Cloud Dataproc

    • Preencha os campos na página Enviar um job da seguinte maneira:
      • Cluster: selecione o nome do cluster na lista de clusters.
      • Tipo de job: Spark.
      • Classe principal ou jar: especifique o caminho do URI do Cloud Storage para seu jar HelloWorld (gs://your-bucket-name/HelloWorld.jar). Se o jar não incluir um manifesto que especifique o ponto de entrada do código ("Main-Class: HelloWorld"), o campo "Classe principal ou jar" deverá indicar o nome da classe principal ("HelloWorld"), e você deverá preencher o campo "Arquivos jar" com o caminho URI para o arquivo jar (gs://your-bucket-name/HelloWorld.jar).
  2. Clique em Enviar para iniciar o job. Depois de iniciado, o job entra na lista de jobs.

  3. Clique no código do job para abrir a página Jobs e ver a saída do driver do job.

Gravar e executar o código do Spark Scala usando o REPL spark-shell

Talvez você queira desenvolver aplicativos em Scala diretamente no cluster do Cloud Dataproc. O Hadoop e o Spark são pré-instalados em clusters do Cloud Dataproc e são configurados com o conector do Cloud Storage, que permite que seu código leia e grave dados diretamente no Cloud Storage.

Este exemplo mostra como incorporar o SSH ao nó mestre do cluster do Cloud Dataproc do projeto, depois usar o REPL spark-shell para criar e executar um aplicativo MapReduce de contagem de palavras em Scala.

  1. Incorpore o SSH ao nó mestre do cluster do Cloud Dataproc.
    1. Acesse a página Clusters do Cloud Dataproc do projeto no Console do Cloud e clique no nome do cluster.
    2. Na página de detalhes do cluster, selecione a guia Instâncias de VM e clique na seleção SSH à direita do nome do nó mestre do cluster.
      Uma janela do navegador é aberta no diretório principal no nó mestre.
          Connected, host fingerprint: ssh-rsa 2048 ...
          ...
          user@clusterName-m:~$
          
  2. Inicie o spark-shell.
        $ spark-shell
        ...
        Using Scala version ...
        Type in expressions to have them evaluated.
        Type :help for more information.
        ...
        Spark context available as sc.
        ...
        SQL context available as sqlContext.
        scala>
        
  3. Crie um RDD (conjunto de dados distribuído resiliente) a partir de um fragmento de texto de Shakespeare localizado no Cloud Storage público.
        scala> val text_file = sc.textFile("gs://pub/shakespeare/rose.txt")
        
  4. Execute um mapreduce de contagem de palavras no texto e exiba o resultado wordcounts.
        scala> val wordCounts = text_file.flatMap(line => line.split(" ")).map(word =>
        (word, 1)).reduceByKey((a, b) => a + b)
        scala> wordCounts.collect
        ... Array((call,1), (What's,1), (sweet.,1), (we,1), (as,1), (name?,1), (any,1), (other,1),
        (rose,1), (smell,1), (name,1), (a,2), (would,1), (in,1), (which,1), (That,1), (By,1))
        
  5. Salve as contagens em <bucket-name>/wordcounts-out no Cloud Storage e saia do scala-shell.
        scala> wordCounts.saveAsTextFile("gs://<bucket-name>/wordcounts-out/")
        scala> exit
        
  6. Use gsutil para listar os arquivos de saída e exibir o conteúdo do arquivo.
        $ gsutil ls gs://<bucket-name>/wordcounts-out/
        gs://spark-scala-demo-bucket/wordcounts-out/
        gs://spark-scala-demo-bucket/wordcounts-out/_SUCCESS
        gs://spark-scala-demo-bucket/wordcounts-out/part-00000
        gs://spark-scala-demo-bucket/wordcounts-out/part-00001
        
  7. Verifique o conteúdo de gs://<bucket-name>/wordcounts-out/part-00000.
        $ gsutil cat gs://<bucket-name>/wordcounts-out/part-00000
        (call,1)
        (What's,1)
        (sweet.,1)
        (we,1)
        (as,1)
        (name?,1)
        (any,1)
        (other,1)
        

Execução de código de exemplo pré-instalado

O nó mestre do Cloud Dataproc contém arquivos jar executáveis com exemplos padrão do Apache Hadoop e do Spark.

Tipo de jar Master node /usr/lib/ location Fonte no GitHub Documentos do Apache
Hadoop hadoop-mapreduce/hadoop-mapreduce-examples.jar link da fonte Tutorial do MapReduce
Spark spark/lib/spark-examples.jar link da fonte Exemplos do Spark

Envio de exemplos ao cluster pela linha de comando

Os exemplos podem ser enviados da sua máquina de desenvolvimento local usando a ferramenta de linha de comando gcloud do SDK do Cloud (consulte Como usar o Console do Google Cloud para enviar jobs a partir do Console do Cloud).

Exemplo de WordCount do Hadoop

    gcloud dataproc jobs submit hadoop --cluster <cluster-name> \
      --jars file:///usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples.jar \
      --class org.apache.hadoop.examples.WordCount \
      -- <URI of input file> <URI of output file>
    

Exemplo de WordCount do Spark

    gcloud dataproc jobs submit spark --cluster <cluster-name> \
      --jars file:///usr/lib/spark/examples/jars/spark-examples.jar \
      --class org.apache.spark.examples.JavaWordCount \
      -- <URI of input file>
    

Encerrar o cluster

Para evitar cobranças contínuas, encerre o cluster e exclua os recursos do Cloud Storage (intervalo e arquivos do Storage) usados neste tutorial.

Para encerrar um cluster:

    gcloud dataproc clusters delete <cluster-name>
    

Para excluir o arquivo jar do Cloud Storage:

    gsutil rm gs://<bucket-name>/HelloWorld.jar
    

Exclua um intervalo e todos os respectivos arquivos e pastas usando o seguinte comando:

    gsutil rm -r gs://<bucket-name>/
    

A seguir

Leia Como gerenciar dependências do Java para aplicativos do Apache Spark no Cloud Dataproc.