我们来深入讲讲 spark-submit。它是将你的PySpark脚本(或Scala/Java应用)提交到Spark集群执行的核心命令行工具。你可以把它想象成启动整个Spark任务的“发射按钮”。
1. spark-submit 是什么?
spark-submit 是一个用于向任何类型的Spark集群(Standalone, Apache Mesos, Hadoop YARN, Kubernetes)提交应用程序的脚本。它位于Spark安装目录的 bin 目录下。它的核心作用是:
- 建立与集群管理器的连接:告诉Spark你的集群资源在哪里(YARN ResourceManager, Standalone Master等)。
- 传输应用依赖:将你的应用JAR包或Python文件,以及任何额外的依赖包(如第三方库)传输到集群中。
- 配置执行环境:设置应用运行所需的所有配置参数(如Executor内存、CPU核心数等)。
- 启动Application:最终在集群上启动你的Spark应用。
2. 一个最基础的提交命令
假设你刚刚在本地测试完一个名为 user_profile_etl.py 的脚本,现在想把它提交到YARN集群上运行。
最最简单的命令如下:
spark-submit \
--master yarn \
user_profile_etl.py
--master yarn:指定集群的主节点地址为YARN模式。Spark会自动读取你Hadoop配置中的YARN ResourceManager地址。user_profile_etl.py:你要提交的Python脚本文件。
但是,在实际生产环境中(尤其是在银行项目里),你绝不会这么简单地提交任务。 你需要精确控制资源、配置和依赖。
3. 生产环境中常用的核心参数详解
以下参数是你必须了解和掌握的。
a. 指定集群模式 (--master)
这是最重要的参数,决定了你的任务在哪里运行。
--master local[*]:在本地模式运行,使用所有CPU核心。仅用于测试。--master yarn:提交到Hadoop YARN集群。这是银行大数据平台最常见的选择。--master spark://host:7077:提交到Standalone模式的Spark集群。--master k8s://https://<k8s-apiserver-host>:<port>:提交到Kubernetes集群。
b. 配置部署模式 (--deploy-mode)
当Master是YARN或Standalone时,可以指定Driver程序的运行位置。
--deploy-mode client(默认值): Driver运行在你提交任务的本地机器上。- 优点:调试方便,可以直接在控制台看到输出和日志。
- 缺点:提交任务的机器必须与集群网络通畅,且如果本地机器断开,任务会失败。
--deploy-mode cluster: Driver程序被YARN随机分配到集群中的某个节点上运行。- 优点:更适合生产环境,提交任务的客户端可以随时关闭,任务不会中断。
- 缺点:查看日志需要通过YARN的Web UI或命令,不如
client模式直观。
银行生产环境通常使用 --master yarn --deploy-mode cluster。
c. 配置资源参数
这些参数决定了你的任务能使用多少集群资源,直接影响执行效率和稳定性。
--executor-memory 4g:为每个Executor分配4GB的内存。--executor-cores 2:为每个Executor分配2个CPU核心。--num-executors 10:为这个Application申请10个Executor实例。--driver-memory 2g:为Driver程序分配2GB内存。(如果数据收集到Driver的操作多,如collect(),这个值要设大一些)--total-executor-cores 20:另一种方式,直接申请总共20个CPU核心,让YARN自己去决定Executor的数量和配置。
一个典型的资源组合示例:
spark-submit \
--master yarn \
--deploy-mode cluster \
--num-executors 20 \
--executor-cores 4 \
--executor-memory 8g \
--driver-memory 2g \
user_profile_etl.py
这个配置申请了20个Executor,每个Executor有4核8G,总计算资源是 80核160G内存。
d. 指定应用配置
你可以动态覆盖Spark应用内部的配置。
--conf spark.sql.shuffle.partitions=200:设置Shuffle操作后的分区数。这对于性能调优至关重要,通常建议设置为num-executors * executor-cores * 2左右。--conf spark.serializer=org.apache.spark.serializer.KryoSerializer:使用Kryo序列化,比Java序列化更快,内存占用更小。
e. 处理依赖
如果你的脚本依赖第三方Python库(如 pandas, numpy),你需要告诉Spark如何把这些包分发给所有工作节点。
--py-files a.py,b.zip,c.egg:提交额外的Python文件或压缩包。你可以将依赖包打包成ZIP文件传到这里。--archives package.tar.gz#alias:提交归档文件,并在工作节点解压。--jars /path/to/jar:提交额外的JAR包(例如,用于连接MySQL、HBase等外部数据源的Connector)。
一个处理依赖的示例(假设你用了pandas):
- 在本地虚拟环境中打包依赖:
pip install pandas -t ./pypacks - 将
pypacks目录压缩:zip -r pypacks.zip pypacks/ - 在spark-submit中指定:
--py-files pypacks.zip
4. 一个完整的、接近生产环境的spark-submit示例
假设我们要提交一个用户画像的特征工程脚本,它依赖一些自定义工具函数(utils.py)和第三方库(已打包),并读取Hive表。
#!/bin/bash
# 使用Spark3的submit命令
/opt/spark3/bin/spark-submit \
--master yarn \
--deploy-mode cluster \
--queue data_team # 指定YARN调度队列 \
# 资源申请
--num-executors 50 \
--executor-cores 4 \
--executor-memory 16g \
--driver-memory 4g \
--conf spark.sql.adaptive.enabled=true \ # 开启AQE,Spark3的重要优化特性
--conf spark.sql.adaptive.coalescePartitions.enabled=true \
--conf spark.sql.shuffle.partitions=400 \ # 分区数 = 50 executors * 4 cores * 2
# 依赖管理
--py-files utils.py,./deps/pypacks.zip \ # 提交工具文件和第三方依赖包
--jars /path/to/mysql-connector-java-8.0.23.jar \ # 提交MySQL连接器JAR包
# Hive支持
--conf spark.sql.catalogImplementation=hive \
# 主应用入口
user_profile_feature_engineering.py \
# 传递给Python脚本本身的参数(可以通过sys.argv获取)
--date 20231027 \
--output-table dw.user_profile_features
5. 如何监控和调试?
提交任务后,你不会在控制台看到大量日志(尤其是在cluster模式下)。你需要通过YARN的Web UI来监控。
- 找到Application ID:任务提交后,命令行会返回一个
Application ID,如application_123456789_0001。 - 访问YARN ResourceManager Web UI:通常地址是
http://<rm-host>:8088。 - 查看日志:在YARN UI中找到你的应用,点击“Logs”即可查看Driver和Executor的详细运行日志,这对于调试错误至关重要。
总结
spark-submit 是你从“编写代码”到“生产运行”的桥梁。在银行项目中,熟练使用 spark-submit 及其各种参数进行资源调优、配置管理和依赖处理,是保证Spark应用稳定、高效运行的关键技能。建议你将常用的提交命令写成一个Shell脚本,方便重复执行和版本管理。

被折叠的 条评论
为什么被折叠?



