Submeta e execute novamente uma aplicação Spark em lote

Big DataBeginner
Pratique Agora

Introdução

Uma aplicação útil em lote deve executar a partir de um programa salvo com entradas e saídas explícitas, sem depender de um DataFrame ou visualização temporária deixada em uma sessão anterior. Você submeterá um programa preparado de vendas diárias em processos separados e conferirá tanto seus resultados salvos quanto as evidências de execução.

spark-submit é o iniciador de aplicações do Spark. Você fornecerá a ele o master de execução, o programa Python e os argumentos de entrada e saída do programa. O script deixa deliberadamente essa configuração externa de master controlar a execução. Sua lógica de relatório repete a leitura tipada, o filtro de pagos, o valor decimal e o agrupamento já aprendidos; o tratamento de argumentos é fornecido para que você se concentre na submissão e em novas execuções seguras.

Este laboratório independente fornece dois recebimentos CSV válidos e o programa completo. Você inspecionará logs e códigos de saída, mudará o caminho de entrada e distinguirá uma entrada ausente de um conflito de saída existente. Não é necessário cluster remoto, empacotamento, agendador, Hive nem estado de processos anteriores. Use o Terminal.

Submeta um programa preparado com argumentos explícitos

Nesta etapa, você processará o primeiro recebimento por uma aplicação independente. Inspecione a origem e o programa fornecido:

cd /home/labex/project
cat /home/labex/project/data/orders.csv
cat /home/labex/project/sales_batch.py

O analisador já aceita input_path, output_path e o --overwrite opcional. Você não precisa implementar argparse. O primeiro caminho posicional é sempre a entrada e o segundo, a saída. O builder da SparkSession não chama master, portanto a configuração --master do iniciador controla a execução.

Leia o comando da esquerda para a direita: as opções de spark-submit precedem o nome do arquivo Python; os argumentos após esse nome vão para a aplicação. Coloque local[2] entre aspas para que o shell trate seus colchetes literalmente. > salva a saída comum, e 2>&1 envia a saída de erro ao mesmo log:

spark-submit --master 'local[2]' /home/labex/project/sales_batch.py /home/labex/project/data/orders.csv /home/labex/project/output/run-1 > /home/labex/project/output/run-1-job.log 2>&1

Colete imediatamente o status de saída antes de executar qualquer outro comando no terminal. $? é o status do comando anterior: zero significa sucesso, e um valor diferente de zero significa falha. printf grava esse valor e uma quebra de linha em um arquivo local de status:

printf '%s\n' "$?" > /home/labex/project/output/run-1-exit-status.txt
cat /home/labex/project/output/run-1-exit-status.txt

Espere 0. Leia o final do log do driver:

tail -n 30 /home/labex/project/output/run-1-job.log

Localize Master: local[2], o ID real da aplicação, os caminhos selecionados de entrada e saída e as datas do relatório. O ID varia. O relatório deverá mostrar 14 de outubro / 2 / 45.00 e 15 de outubro / 2 / 80.00. Um código de saída zero junto com um resultado Parquet real correto é uma evidência mais forte do que uma linha tranquilizadora de log.

O programa cria e encerra sua própria sessão. Ele não reutilizou as visualizações nem as variáveis Python da lição anterior.

Mude a entrada em um novo processo

Nesta etapa, você comprovará que o programa deriva seu resultado do caminho fornecido. Inspecione o segundo recebimento:

cat /home/labex/project/data/new-orders.csv

Ele tem dois pedidos pagos em 16 de outubro, com valores 30.00 e 25.00, além de um pedido pendente. Preveja uma linha de relatório: contagem 2 e receita 55.00. Mantenha a primeira saída e submeta este novo arquivo a um destino separado:

spark-submit --master 'local[2]' /home/labex/project/sales_batch.py /home/labex/project/data/new-orders.csv /home/labex/project/output/run-2 > /home/labex/project/output/run-2-job.log 2>&1
printf '%s\n' "$?" > /home/labex/project/output/run-2-exit-status.txt
cat /home/labex/project/output/run-2-exit-status.txt
tail -n 30 /home/labex/project/output/run-2-job.log

Espere status 0 e o resultado previsto de 16 de outubro. Seu ID real de aplicação é diferente do primeiro processo. O programa carregou o novo caminho e criou sua própria sessão; uma visualização remanescente não foi necessária.

Tanto run-1 quanto run-2 continuam disponíveis, tornando inspecionável a relação entre cada entrada e seu resultado. Não mude o arquivo de origem apenas para fazer uma resposta memorizada aparecer.

Diagnostique separadamente entrada ausente e saída existente

Nesta etapa, você coletará duas falhas distintas de caminho sem excluir dados. Primeiro, submeta uma entrada inexistente. Espera-se que o próximo comando falhe.

spark-submit --master 'local[2]' /home/labex/project/sales_batch.py /home/labex/project/data/missing-orders.csv /home/labex/project/output/unused-missing-input > /home/labex/project/output/missing-input.log 2>&1

Colete seu status imediatamente, antes de inspecionar o log:

printf '%s\n' "$?" > /home/labex/project/output/missing-input-exit-status.txt
cat /home/labex/project/output/missing-input-exit-status.txt
tail -n 25 /home/labex/project/output/missing-input.log

Espere um status diferente de zero e um diagnóstico de caminho não encontrado nomeando missing-orders.csv. Corrigir o caminho de entrada resolve esse problema; mudar o master ou recriar um cluster não resolve.

O modo padrão errorifexists do script também protege um destino existente. Tente a entrada conhecida no caminho run-1 já concluído. Espera-se que o próximo comando falhe.

spark-submit --master 'local[2]' /home/labex/project/sales_batch.py /home/labex/project/data/orders.csv /home/labex/project/output/run-1 > /home/labex/project/output/existing-output.log 2>&1
printf '%s\n' "$?" > /home/labex/project/output/existing-output-exit-status.txt
cat /home/labex/project/output/existing-output-exit-status.txt
tail -n 25 /home/labex/project/output/existing-output.log

Espere um status diferente de zero e um diagnóstico de saída já existente. Isso difere de uma entrada ausente, e o relatório anterior bem-sucedido deverá permanecer intacto.

Faça um reparo que preserve o trabalho usando a origem correta e um novo diretório de saída:

spark-submit --master 'local[2]' /home/labex/project/sales_batch.py /home/labex/project/data/orders.csv /home/labex/project/output/run-3 > /home/labex/project/output/run-3-job.log 2>&1
printf '%s\n' "$?" > /home/labex/project/output/run-3-exit-status.txt
cat /home/labex/project/output/run-3-exit-status.txt
tail -n 25 /home/labex/project/output/run-3-job.log

Espere sucesso e os dois totais diários originais. Um novo destino mantém ambos os recebimentos anteriores e as evidências de falhas, sem remover arquivos brutos nem árvores amplas de saída.

Reconstrua explicitamente um retrato derivado pretendido

Nesta etapa, você escolherá deliberadamente a substituição para um retrato completo conhecido. O argumento opcional --overwrite já está implementado: ele muda apenas o modo de gravação do destino deste programa para overwrite. Não altera a entrada, outros caminhos de resultado nem o master externo do Spark.

Use-o quando sua intenção for reconstruir todo o resultado derivado especificado a partir da mesma origem. Aqui, run-1 é esse retrato conhecido; as outras execuções e entradas brutas permanecem separadas:

spark-submit --master 'local[2]' /home/labex/project/sales_batch.py /home/labex/project/data/orders.csv /home/labex/project/output/run-1 --overwrite > /home/labex/project/output/overwrite-job.log 2>&1
printf '%s\n' "$?" > /home/labex/project/output/overwrite-exit-status.txt
cat /home/labex/project/output/overwrite-exit-status.txt
tail -n 30 /home/labex/project/output/overwrite-job.log

Espere status 0, Write mode: overwrite e as mesmas duas linhas do relatório. Este novo processo substitui o retrato em vez de adicionar datas duplicadas. Seu ID de aplicação difere da primeira execução, e seu log tem seu próprio nome de arquivo.

Você praticou duas respostas válidas a uma saída existente: escolher um novo caminho quando manter ambas as versões importa ou reconstruir explicitamente um retrato derivado conhecido quando a substituição é intencional. Erros de caminho de entrada ainda exigem uma entrada correta; sobrescrita não é um reparo para dados ausentes. Esses hábitos de submissão e repetição preparam você para o desafio final de pipeline reutilizável de vendas.

Resumo

Você iniciou uma aplicação Spark parametrizada em processos independentes, coletou status e logs reais e verificou resultados para entradas diferentes. Distinguiu uma entrada ausente de um conflito de saída existente e escolheu um novo destino ou uma substituição explícita do retrato. O desafio final agora combina esses hábitos de submissão com limpeza, enriquecimento, agregação e saída particionada.