Como usar o Spark no Kubernetes Engine para processar dados no BigQuery

Neste tutorial, mostramos como criar e executar um pipeline de dados que usa o BigQuery para armazenar dados e o Spark no Google Kubernetes Engine (GKE) para processar esses dados. Esse pipeline é útil para equipes que tenham uma infraestrutura padronizada de computação no GKE e que estejam procurando maneiras de migrar os fluxos de trabalho atuais. Para a maioria das equipes, executar o Spark no Cloud Dataproc é a maneira mais fácil e escalonável de executar aplicativos Spark. No tutorial, avaliamos um conjunto de dados público do BigQuery, dados do GitHub, para encontrar projetos que mais se beneficiariam de uma contribuição. Neste tutorial, presumimos que você saiba usar o GKE e o Apache Spark. O diagrama geral de arquitetura a seguir mostra as tecnologias que você usará.

diagrama da arquitetura

Muitos projetos no GitHub são escritos em Go, mas poucos indicadores dizem aos colaboradores que um projeto precisa de ajuda ou onde a base de código precisa de mais atenção.

Neste tutorial, você usa os seguintes indicadores para saber se um projeto precisa de contribuições:

  • número de problemas em aberto
  • número de colaboradores
  • número de vezes que os pacotes de um projeto são importados por outros projetos
  • frequência dos comentários FIXME ou TODO

O diagrama a seguir mostra o pipeline do aplicativo Spark:

Pipeline de aplicativos Spark

Objetivos

  • Criar um cluster do Kubernetes Engine para executar seu aplicativo Spark.
  • Implantar um aplicativo Spark no Kubernetes Engine.
  • Consultar e escrever tabelas do BigQuery no aplicativo Spark.
  • Analisar os resultados usando o BigQuery.

Custos

Neste tutorial, há componentes faturáveis do Google Cloud, entre eles:

Use a calculadora de preços para gerar uma estimativa de custo com base no uso previsto. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Antes de começar

  1. Faça login na sua conta do Google.

    Se você ainda não tiver uma, inscreva-se.

  2. No Console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar a página do seletor de projetos

  3. Verifique se o faturamento está ativado para seu projeto na nuvem. Saiba como confirmar se o faturamento está ativado para o projeto.

  4. Ative as APIs Kubernetes Engine and BigQuery.

    Ative as APIs

Configurar o ambiente

Nesta seção, você define as configurações do projeto necessárias para concluir o tutorial.

Iniciar uma instância do Cloud Shell

Abra o Cloud Shell

Você trabalha com o restante do tutorial no Cloud Shell.

Como executar o pipeline manualmente

Nas etapas seguintes, você inicia seu pipeline fazendo o BigQuery extrair todos os arquivos com a extensão .go da tabela sample_files, que é um subconjunto de [bigquery-public-data:github_repos.files]. Usar o subconjunto de dados permite testar de maneira mais econômica.

  1. No Cloud Shell, execute os comandos a seguir para criar um novo conjunto de dados e uma nova tabela no BigQuery. Eles servem para armazenar os resultados intermediários da consulta:

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq mk --project_id $PROJECT spark_on_k8s_manual
    bq mk --project_id $PROJECT spark_on_k8s_manual.go_files
    
  2. Veja uma amostra dos arquivos Go provenientes do conjunto de dados do repositório GitHub. Em seguida, armazene os arquivos em uma tabela intermediária com a opção --destination_table:

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq query --project_id $PROJECT --replace \
             --destination_table spark_on_k8s_manual.go_files \
        'SELECT id, repo_name, path FROM
    [bigquery-public-data:github_repos.sample_files]
         WHERE RIGHT(path, 3) = ".go"'
    

    Você verá os caminhos de arquivos listados com o repositório de onde eles vieram. Exemplo:

    Waiting on bqjob_r311c807f17003279_0000015fb8007c47_1 ... (0s) Current status: DONE
    +------------------------------------------+------------------+-------------------------+
    |                    id                    |    repo_name     |          path           |
    +------------------------------------------+------------------+-------------------------+
    | 31a4559c1e636e | mandelsoft/spiff | spiff++/spiff.go        |
    | 15f7611dd21a89 | bep/gr           | examples/router/main.go |
    | 15cbb0b0f096a2 | knq/xo           | internal/fkmode.go      |
    +------------------------------------------+------------------+-------------------------+
    

    A lista de todos os arquivos Go identificados é armazenada na tabela spark_on_k8s_manual.go_files.

  3. Execute a consulta a seguir para exibir os 10 primeiros caracteres de cada arquivo.

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq query --project_id $PROJECT 'SELECT sample_repo_name as
    repo_name, SUBSTR(content, 0, 10) FROM
    [bigquery-public-data:github_repos.sample_contents] WHERE id IN
    (SELECT id FROM spark_on_k8s_manual.go_files)'
    

Como executar o pipeline com o Spark no Kubernetes

Em seguida, você automatiza um procedimento similar com um aplicativo Spark que usa o conector spark-bigquery para executar consultas SQL diretamente com o BigQuery. Em seguida, o aplicativo manipula os resultados e os salva no BigQuery usando a Spark SQL API e a DataFrames API.

Criar um cluster do Kubernetes Engine

Para implementar o Spark e o aplicativo de exemplo, crie um cluster do Kubernetes Engine executando os seguintes comandos:

gcloud config set compute/zone us-central1-f
gcloud container clusters create spark-on-gke --machine-type n1-standard-2

Fazer o download do código de exemplo

Clone o repositório do aplicativo de exemplo:

git clone https://github.com/GoogleCloudPlatform/spark-on-k8s-gcp-examples.git
cd spark-on-k8s-gcp-examples/github-insights

Configure o gerenciamento de identidade e acesso

Crie uma conta de serviço do Identity and Access Management (IAM) para conceder ao Spark acesso ao BigQuery.

  1. Crie a conta de serviço:

    gcloud iam service-accounts create spark-bq --display-name spark-bq
    
  2. Armazene o endereço de e-mail da conta de serviço e o código do projeto atual nas variáveis de ambiente a serem usadas em comandos posteriores:

    export SA_EMAIL=$(gcloud iam service-accounts list --filter="displayName:spark-bq" --format='value(email)')
    export PROJECT=$(gcloud info --format='value(config.project)')
    
  3. É necessário que o aplicativo de amostra crie e manipule conjuntos de dados e tabelas do BigQuery e remova artefatos do Cloud Storage. Vincule os papéis bigquery.dataOwner, bigQuery.jobUser e storage.admin à conta de serviço:

    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/storage.admin
    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/bigquery.dataOwner
    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/bigquery.jobUser
    
  4. Faça o download da chave JSON da conta de serviço e armazene-a em uma chave secreta do Kubernetes. Os drivers e executores do Spark usam essa chave secreta para fazer a autenticação com o BigQuery:

    gcloud iam service-accounts keys create spark-sa.json --iam-account $SA_EMAIL
    kubectl create secret generic spark-sa --from-file=spark-sa.json
    
  5. Adicione permissões para que o Spark possa iniciar jobs no cluster do Kubernetes.

    kubectl create clusterrolebinding user-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
    kubectl create clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:default spark-admin
    

Configurar e executar o aplicativo Spark

Agora você faz o download, instala e configura o Spark para executar o aplicativo Spark de amostra no seu cluster do Kubernetes Engine.

  1. Instale o Maven, que você usa para gerenciar o processo de criação do aplicativo de amostra:

    sudo apt-get install -y maven
  2. Crie o jar do aplicativo de amostra:

    mvn clean package
  3. Crie um bucket do Cloud Storage para armazenar o jar do aplicativo e os resultados do pipeline do Spark:

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb gs://$PROJECT-spark-on-k8s
    
  4. Faça o upload do jar do aplicativo para o bucket do Cloud Storage:

    gsutil cp target/github-insights-1.0-SNAPSHOT-jar-with-dependencies.jar \
                   gs://$PROJECT-spark-on-k8s/jars/
    
  5. Crie um novo conjunto de dados do BigQuery:

    bq mk --project_id $PROJECT spark_on_k8s
  6. Faça o download da distribuição oficial do Spark 2.3 e desarquive-a:

    wget https://archive.apache.org/dist/spark/spark-2.3.0/spark-2.3.0-bin-hadoop2.7.tgz
    tar xvf spark-2.3.0-bin-hadoop2.7.tgz
    cd spark-2.3.0-bin-hadoop2.7
    
  7. Configure o aplicativo do Spark criando um arquivo de propriedades que contenha as informações específicas do projeto:

    cat > properties << EOF
    spark.app.name  github-insights
    spark.kubernetes.namespace default
    spark.kubernetes.driverEnv.GCS_PROJECT_ID $PROJECT
    spark.kubernetes.driverEnv.GOOGLE_APPLICATION_CREDENTIALS /mnt/secrets/spark-sa.json
    spark.kubernetes.container.image gcr.io/cloud-solutions-images/spark:v2.3.0-gcs
    spark.kubernetes.driver.secrets.spark-sa  /mnt/secrets
    spark.kubernetes.executor.secrets.spark-sa /mnt/secrets
    spark.driver.cores 0.1
    spark.executor.instances 3
    spark.executor.cores 1
    spark.executor.memory 512m
    spark.executorEnv.GCS_PROJECT_ID    $PROJECT
    spark.executorEnv.GOOGLE_APPLICATION_CREDENTIALS /mnt/secrets/spark-sa.json
    spark.hadoop.google.cloud.auth.service.account.enable true
    spark.hadoop.google.cloud.auth.service.account.json.keyfile /mnt/secrets/spark-sa.json
    spark.hadoop.fs.gs.project.id $PROJECT
    EOF
    
  8. Execute o aplicativo Spark no conjunto de dados do GitHub de exemplo usando os comandos abaixo:

    export KUBERNETES_MASTER_IP=$(gcloud container clusters list --filter name=spark-on-gke --format='value(MASTER_IP)')
    bin/spark-submit \
    --properties-file properties \
    --deploy-mode cluster \
    --class spark.bigquery.example.github.NeedingHelpGoPackageFinder \
    --master k8s://https://$KUBERNETES_MASTER_IP:443 \
    --jars http://central.maven.org/maven2/com/databricks/spark-avro_2.11/4.0.0/spark-avro_2.11-4.0.0.jar \
    gs://$PROJECT-spark-on-k8s/jars/github-insights-1.0-SNAPSHOT-jar-with-dependencies.jar \
    $PROJECT spark_on_k8s $PROJECT-spark-on-k8s --usesample
    
  9. Abra uma nova sessão do Cloud Shell clicando no botão Adicionar sessão do Cloud Shell:

    Botão &quot;Adicionar sessão do Cloud Shell&quot;

  10. Na nova sessão do Cloud Shell, veja os registros do pod de driver usando o comando a seguir para acompanhar o andamento do aplicativo. Ele leva cerca de cinco minutos para ser executado.

    kubectl logs -l spark-role=driver
  11. Quando a execução do aplicativo for concluída, verifique os 10 pacotes mais acessados. Basta executar o seguinte comando:

    bq query "SELECT * FROM spark_on_k8s.popular_go_packages
    ORDER BY popularity DESC LIMIT 10"
    

Execute o mesmo pipeline no grupo completo de tabelas no conjunto de dados do GitHub. Basta remover a opção --usesample na etapa 8. Observe que o tamanho do conjunto de dados completo é muito maior do que o do conjunto de dados de exemplo. Portanto, você provavelmente precisará de um cluster maior para executar o pipeline até a conclusão em um período razoável.

Limpeza

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Depois de concluir o tutorial do Spark no Kubernetes Engine, limpe os recursos criados no Google Cloud para que eles não ocupem a cota, e você não seja cobrado por eles no futuro. Veja como excluir e desativar esses recursos nas seções a seguir.

Como excluir o projeto

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para o tutorial.

Para excluir o projeto:

  1. No Console do Cloud, acesse a página Gerenciar recursos:

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

A seguir

  • Confira outro exemplo de uso do Spark com o BigQuery e o Dataproc.
  • Veja este tutorial que usa o Cloud Dataproc, o BigQuery e o Apache Spark ML para machine learning.

  • Teste outros recursos do Google Cloud. Veja nossos tutoriais.