Envíe y repita una aplicación por lotes de Spark

Big DataBeginner
Practicar Ahora

Introducción

Una aplicación útil por lotes debería ejecutarse desde un programa guardado con entradas y salidas explícitas, sin depender de un DataFrame o una vista temporal que haya quedado en una sesión anterior. Enviará un programa preparado de ventas diarias en procesos separados y comprobará tanto sus resultados guardados como su evidencia de ejecución.

spark-submit es el lanzador de aplicaciones de Spark. Le proporcionará el master de ejecución, el programa Python y los argumentos de entrada y salida del programa. El script deja deliberadamente que ese ajuste externo de master controle la ejecución. Su lógica de informes repite la lectura con tipos, el filtro de pagados, el importe decimal y la agrupación ya aprendidos; el análisis de argumentos está proporcionado para que pueda centrarse en el envío y las repeticiones cuidadosas.

Este laboratorio independiente proporciona dos entregas CSV válidas y el programa completo. Examinará registros y códigos de salida, cambiará la ruta de entrada y distinguirá una entrada inexistente de un conflicto de salida existente. No se requiere clúster remoto, empaquetado, planificador, Hive ni estado de un proceso anterior. Utilice Terminal.

Envíe un programa preparado con argumentos explícitos

En este paso, procesará la primera entrega mediante una aplicación independiente. Examine el origen y el programa proporcionado:

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

El analizador ya acepta input_path, output_path y la opción --overwrite. No necesita implementar argparse. La primera ruta posicional siempre es la entrada y la segunda la salida. El constructor de SparkSession no llama a master, por lo que el ajuste --master del lanzador controla la ejecución.

Lea el comando de izquierda a derecha: las opciones de spark-submit preceden al nombre del archivo Python; los argumentos posteriores a ese nombre van a la aplicación. Ponga local[2] entre comillas para que el shell trate sus corchetes literalmente. > guarda la salida normal y 2>&1 envía la salida de error al mismo registro:

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

Capture inmediatamente el estado de salida antes de ejecutar cualquier otro comando de terminal. $? es el estado del comando anterior: cero significa éxito y un valor distinto de cero significa fallo. printf escribe ese valor y un salto de línea en un archivo local de estado:

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

Espere 0. Lea el final del registro del controlador:

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

Busque Master: local[2], el ID real de aplicación, las rutas seleccionadas de entrada y salida y las fechas del informe. El ID varía. El informe debería mostrar 14 de octubre / 2 / 45.00 y 15 de octubre / 2 / 80.00. Un código de salida cero junto con un resultado Parquet real correcto es evidencia más sólida que una línea tranquilizadora de registro.

El programa crea y detiene su propia sesión. No reutilizó vistas ni variables Python de la lección anterior.

Cambie la entrada en un proceso nuevo

En este paso, demostrará que el programa deriva su resultado de la ruta proporcionada. Examine la segunda entrega:

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

Tiene dos pedidos pagados el 16 de octubre, con importes 30.00 y 25.00, más un pedido pendiente. Prediga una fila de informe: conteo 2 e ingresos 55.00. Conserve la primera salida y envíe este archivo nuevo a un 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 estado 0 y el resultado previsto del 16 de octubre. Su ID real de aplicación difiere del primer proceso. El programa cargó la ruta nueva y creó su propia sesión; no se necesitó una vista que hubiera quedado de antes.

run-1 y run-2 permanecen disponibles, haciendo posible examinar la relación entre cada entrada y resultado. No cambie el archivo de origen solo para que aparezca una respuesta memorizada.

Diagnostique por separado una entrada ausente y una salida existente

En este paso, guardará dos fallos distintos de rutas sin eliminar datos. Primero envíe una entrada inexistente. Se espera que el siguiente comando falle.

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

Capture su estado inmediatamente, antes de examinar el registro:

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 un estado distinto de cero y un diagnóstico de ruta no encontrada que nombre missing-orders.csv. Corregir la ruta de entrada resuelve este problema; cambiar el master o recrear un clúster no lo hace.

El modo predeterminado errorifexists del script también protege un destino existente. Pruebe la entrada conocida contra la ruta run-1 ya completada. Se espera que el siguiente comando falle.

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 un estado distinto de cero y un diagnóstico de salida ya existente. Esto difiere de una entrada ausente y el informe anterior correcto debería permanecer intacto.

Realice una reparación que priorice la conservación utilizando el origen correcto y un directorio nuevo de salida:

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 éxito y los dos totales diarios originales. Un destino nuevo conserva ambas entregas anteriores y la evidencia de fallo, sin eliminar archivos originales ni árboles amplios de salida.

Reconstruya explícitamente una instantánea derivada prevista

En este paso, elegirá deliberadamente la sustitución para una instantánea completa conocida. El argumento opcional --overwrite ya está implementado: cambia únicamente el modo de escritura del destino de este programa a overwrite. No altera la entrada, otras rutas de resultados ni el master externo de Spark.

Utilícelo cuando su intención sea reconstruir todo el resultado derivado especificado desde el mismo origen. Aquí run-1 es esa instantánea conocida; las otras ejecuciones y entradas originales permanecen 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 estado 0, Write mode: overwrite y las mismas dos filas de informe. Este proceso nuevo sustituye la instantánea en lugar de añadir fechas duplicadas. Su ID de aplicación difiere de la primera ejecución y su registro tiene su propio nombre de archivo.

Ha practicado dos respuestas válidas a una salida existente: elegir una ruta nueva cuando importe conservar ambas versiones o reconstruir explícitamente una instantánea derivada conocida cuando se pretenda sustituirla. Los errores de ruta de entrada siguen requiriendo una entrada correcta; sobrescribir no repara datos ausentes. Estos hábitos de envío y repetición le preparan para el desafío final de una canalización reutilizable de ventas.

Resumen

Lanzó una aplicación parametrizada de Spark en procesos independientes, capturó estados y registros reales y verificó resultados para entradas diferentes. Distinguió una entrada ausente de un conflicto de salida existente y eligió un destino nuevo o una sustitución explícita de instantánea. El desafío final combina ahora estos hábitos de envío con limpieza, enriquecimiento, agregación y salida particionada.