提交并重新运行 Spark 批处理应用

大数据Beginner
立即练习

介绍

实用的批处理应用应通过保存的程序和明确输入输出运行,不依赖先前会话中留下的 DataFrame 或临时视图。你将在独立进程中提交预置每日销售程序,并检查存储结果和执行证据。

spark-submit 是 Spark 应用启动器。你将向它提供执行 master、Python 程序及程序的输入输出参数。脚本有意让外部 master 设置控制执行。报表逻辑重复已学的有类型读取、已付款筛选、十进制金额和分组;参数解析已提供,让你专注于提交和安全重跑。

本独立实验提供两个有效 CSV 文件和完整程序。你将查看日志和退出码,改变输入路径,并区分输入缺失与输出已存在的冲突。无需远程集群、打包、调度器、Hive 或之前进程状态。请使用终端。

使用明确参数提交预置程序

在这一步中,你将通过独立应用处理第一个文件。查看源数据和提供的程序:

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

解析器已经接受 input_path、output_path 和可选 --overwrite,无需实现 argparse。第一个位置路径始终是输入,第二个是输出。SparkSession 构建器没有调用 master,因此启动器的 --master 设置控制执行。

从左往右理解命令:spark-submit 选项放在 Python 文件名之前,文件名之后的参数传给应用。为 local[2] 加引号,让 Shell 原样处理方括号。> 保存普通输出,2>&1 将错误输出发往同一个日志:

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

在运行任何其他终端命令之前,立即保存退出状态。$? 是前一条命令的状态:零表示成功,非零表示失败。printf 将该值和换行写入本地状态文件:

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

预期为 0。读取驱动程序日志末尾:

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

找到 Master: local[2]、实际应用 ID、所选输入输出路径和报表日期。ID 会变化。报表应显示 10 月 14 日 / 2 / 45.00 和 10 月 15 日 / 2 / 80.00。零退出码加上正确的实际 Parquet 结果,比单独一行看似正常的日志更有说服力。

程序自行创建并停止会话,没有复用之前课程的视图或 Python 变量。

在新进程中改变输入

在这一步中,你将证明程序根据提供的路径推导结果。查看第二批数据:

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

其中有 10 月 16 日的两笔已付款订单,金额 30.00、25.00,还有一笔待付款订单。预测报表只有一行:计数 2,收入 55.00。保留第一次输出,将这个新文件提交到独立目标:

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

预期状态为 0,结果符合预测的 10 月 16 日汇总。实际应用 ID 与第一个进程不同。程序加载新路径并创建自己的会话,不需要遗留视图。

run-1 和 run-2 都保持可用,让每个输入与结果的关系可检查。不要仅仅为了让记住的答案出现而改变源文件。

分别诊断输入缺失和输出已存在

在这一步中,你将在不删除数据的情况下保存两种不同路径失败。先提交不存在的输入。下一条命令预期失败。

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

查看日志前,立即保存状态:

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

预期为非零状态,并有指出 missing-orders.csv 的路径不存在诊断。修正输入路径才能处理这个问题;改变 master 或重建集群都不行。

脚本默认的 errorifexists 模式也会保护已有目标。用已知输入尝试写入已完成的 run-1 路径。下一条命令预期失败。

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

预期为非零状态,并有输出已存在诊断。这不同于输入缺失,之前成功的报表应保持完整。

使用正确源文件和新输出目录,采取优先保留已有结果的修复方式:

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

预期成功,并生成原来的两个每日总计。新目标保留两次先前交付及失败证据,无需移除原始文件或大范围输出目录树。

明确重建目标派生快照

在这一步中,你将为已知完整快照有意识地选择替换。可选 --overwrite 参数已实现,只将本程序目标写模式改为 overwrite,不改变输入、其他结果路径或 Spark 外部 master。

当你希望从相同源重建整个指定派生结果时,可以使用它。这里 run-1 就是已知快照,其他运行与原始输入保持独立:

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

预期状态为 0,显示 Write mode: overwrite,以及相同的两条报表行。新进程替换快照,不增加重复日期。应用 ID 与第一次运行不同,日志也有独立文件名。

你已练习面对已有输出的两种有效方法:需要保留两个版本时选择新路径,明确希望替换时重建已知派生快照。输入路径错误仍需正确输入;覆盖不能修复数据缺失。这些提交和重跑习惯将为最终可复用销售流水线挑战做准备。

总结

你在独立进程中启动参数化 Spark 应用,保存实际状态与日志,并验证不同输入的结果。你区分了输入缺失与输出已存在冲突,选择新目标或明确快照替换。最终挑战将结合这些提交习惯与清洗、信息补充、聚合及分区输出。