PySpark 提交模式对比与实践推荐

目录

[1. 核心机制更正与说明](#1. 核心机制更正与说明)

[2. 三种方式详细对比](#2. 三种方式详细对比)

[2.1 方式一:Gateway 本地直传模式 (Client-Side Staging)](#2.1 方式一:Gateway 本地直传模式 (Client-Side Staging))

[2.1.1 核心命令参数](#2.1.1 核心命令参数)

[2.1.2 执行原理与流程图](#2.1.2 执行原理与流程图)

[2.2 方式二:HDFS 静态引用模式 (Server-Side Reference)](#2.2 方式二:HDFS 静态引用模式 (Server-Side Reference))

[2.2.1 核心命令参数](#2.2.1 核心命令参数)

[2.2.2 执行原理与流程图](#2.2.2 执行原理与流程图)

[2.3 方式三:流式注入极简模式 (Script-Only)](#2.3 方式三:流式注入极简模式 (Script-Only))

[2.3.1 核心命令参数](#2.3.1 核心命令参数)

[2.3.2 执行原理](#2.3.2 执行原理)

[4. 推荐优先级与最佳实践路线图](#4. 推荐优先级与最佳实践路线图)

[4.1 开发与调试(推荐使用 方式一)](#4.1 开发与调试(推荐使用 方式一))

[4.2 测试与准生产(过渡到 方式二)](#4.2 测试与准生产(过渡到 方式二))

[4.3 生产环境(必须使用 方式二)](#4.3 生产环境(必须使用 方式二))

[5. 总结](#5. 总结)

1. 核心机制更正与说明

在对比之前,先明确 submit_job240.py(方式一)和 submit_job.py(方式二)在资源分发上的本质区别:

  • Spark 的 Staging 机制 :当 spark-submit 的参数(如 --archives, --jars, --files)指向 本地文件系统(file://) 时,Spark 客户端会在任务启动前,先将这些文件 Upload 到 HDFS 的 .sparkStaging/application_id/ 目录下。

  • 方式一:利用了 Spark 的自动 Upload 机制。

  • 方式二:跳过了 Upload 步骤,直接引用 HDFS 上已存在的文件。


2. 三种方式详细对比

2.1 方式一:Gateway 本地直传模式 (Client-Side Staging)

核心特征:依赖提交机(Gateway)本地文件,利用 Spark Client 自动分发。

2.1.1 核心命令参数

在 Python 脚本中构建的 spark-submit 核心参数如下:

python 复制代码
# 关键点:路径指向 Gateway 本地文件系统 (无 hdfs:// 前缀)
spark-submit \
  --master yarn \
  --deploy-mode client \
  # 1. 自动上传:Spark Client 会自动将此本地包上传到 HDFS 临时目录
  --archives "/root/pyspark_test/pyspark_env.tar.gz#python37_dir" \
  # 2. 陷阱:extraClassPath 仅仅是追加 classpath 字符串,不会触发上传
  # 必须配合 --jars 或确保所有节点本地都有该文件
  --conf "spark.driver.extraClassPath=/root/jul-to-slf4j-1.7.25.jar" \
  --conf "spark.executor.extraClassPath=/root/jul-to-slf4j-1.7.25.jar" \
  ...

2.1.2 执行原理与流程图

此模式利用了 Spark 的 Distributed Cache (Staging) 机制。

  • 原理 :当检测到路径为本地路径(file:// 或无前缀)时,Spark 客户端会在任务启动前,先将文件 Upload 到 HDFS 的 .sparkStaging 目录。

  • 适用场景开发调试阶段。环境包/Jar包变动频繁,无需手动维护 HDFS 文件,脚本改完即跑,最为灵活。

2.2 方式二:HDFS 静态引用模式 (Server-Side Reference)

核心特征:依赖 HDFS 预存文件,跳过上传步骤,生产环境标准。

2.2.1 核心命令参数

python 复制代码
# 关键点:路径指向 HDFS (hdfs:// 前缀)
spark-submit \
  --master yarn \
  --deploy-mode client \
  # 1. 静态引用:直接告诉 YARN 去哪里下载,Client 不执行上传动作
  --archives "hdfs:///user/bigdata/env/pyspark_env.tar.gz#python37_dir" \
  ...

2.2.2 执行原理与流程图

此模式跳过了 Client 到 HDFS 的上传阶段,实现了 一次上传,多次分发

详细流程图如下:

  • 原理:Spark Client 仅将 HDFS 路径传递给 ApplicationMaster,Executor 启动时直接从 HDFS 公共目录拉取资源。

  • 适用场景生产调度阶段 。避免了每次调度运行都重复上传 500MB+ 的环境包,减轻 HDFS NameNode 压力,且具有幂等性(任何机器提交效果一致)。

2.3 方式三:流式注入极简模式 (Script-Only)

核心特征:无外部依赖,代码动态生成,仅依赖集群系统环境。

2.3.1 核心命令参数

python 复制代码
# 关键点:没有任何 --archives 或环境依赖参数
spark-submit \
  --master yarn \
  --deploy-mode client \
  # 仅依赖集群节点上 /usr/bin/python2.7 (默认)
  --conf spark.yarn.appMasterEnv.PYSPARK_PYTHON=/usr/bin/python \
  /tmp/temp_script_generated_by_ssh.py

2.3.2 执行原理

  • 原理:不分发 Python 虚拟环境,直接使用 YARN NodeManager 所在机器的操作系统自带 Python。

  • 适用场景冒烟测试 / 连通性检查。验证集群是否存活,不涉及复杂业务库(Pandas/Numpy 等)。

特性 方式一:Gateway 本地直传模式 (submit_job240.py) 方式二:HDFS 静态引用模式 (submit_job.py) 方式三:流式注入模式 (test_spark2.py)
资源位置 Linux 提交机(Gateway)本地磁盘 HDFS 分布式文件系统 代码字符串内嵌
分发机制 自动上传:Spark Client 启动时将本地文件传至 HDFS Staging 目录,再由 YARN 分发。 直接下载:Spark Client 仅传递 HDFS 路径,Executor 直接从 HDFS 下载。 即时生成:脚本在提交机临时生成,仅分发主程序文件。
灵活性 ⭐⭐⭐ (高) 修改依赖(如 Jar 或 Env)后,直接提交即可,无需手动执行 hdfs dfs -put ⭐⭐ (中) 依赖若有更新,必须先手动上传覆盖 HDFS 文件,再提交任务。 ⭐ (低) 环境依赖由于受限于集群预装,无法灵活变更。
提交耗时 较慢 每次提交都需要等待文件上传(尤其是几百 MB 的 Env 包)。 极快 无上传过程,毫秒级响应提交请求。 文件极小。
适用场景 开发/调试/频变依赖 适合依赖包频繁迭代的阶段。 生产/定版/大文件 适合依赖包稳定、版本固定的生产调度。 冒烟测试/连通性检查 验证集群基础状态。
潜在风险 提交机(Gateway)若网络上行带宽不足,会阻塞任务启动。 若 HDFS 文件被误删或覆盖,会影响所有引用该文件的任务。 功能受限,难以维护复杂逻辑。

4. 推荐优先级与最佳实践路线图

根据"灵活性"与"稳定性"的权衡,推荐的优先级如下:

4.1 开发与调试(推荐使用 方式一)

场景:业务逻辑在变,依赖包也在变(比如在测试不同的 Python 库版本)。

  • 做法

    • 在提交机(240)上维护一套 Python 环境和 Jar 包。

    • 使用指向本地路径的脚本提交。

    • 理由 :避免了每次修改环境都要手动 hdfs dfs -put 的繁琐操作,极大提高了迭代效率。

4.2 测试与准生产(过渡到 方式二)

场景:环境依赖已经确定,不再频繁变更,开始进行每日定时调度测试。

  • 做法

    • 将确认好的 pyspark_env.tar.gz.jar 上传到 HDFS 的公共库目录(如 /user/lib/)。

    • 修改提交脚本,指向 HDFS 路径。

    • 理由:避免每次调度都重复上传 500MB+ 的环境包,减轻 HDFS NameNode 和网络带宽的压力,缩短任务启动时间。

4.3 生产环境(必须使用 方式二)

场景:正式上线,SLA 要求高。

  • 做法

    • 严格禁止依赖本地文件(防止提交机故障导致任务无法由其他机器接管)。

    • 使用 HDFS 路径,并做好权限控制(Read-Only)。

    • 理由幂等性高可用。无论从哪台机器提交任务,只要指向同一个 HDFS 路径,任务运行结果都是一致的。

5. 总结

  • submit_job240.py (方式一)最灵活 。本质是 "Client-Side Staging" 。它利用 Spark 帮你把本地文件搬运到 HDFS 临时目录。适合开发迭代,但要注意 extraClassPath 不会自动搬运 Jar 的陷阱。

  • submit_job.py (方式二)最规范 。本质是 "Server-Side Reference"。它假设资源已就位,效率最高,适合生产。

  • test_spark2.py (方式三)最快验证。适合非业务的连通性测试。

结论 :在你的当前场景(可能是在调试环境或代码),方式一(240脚本)确实是最好用的,只要修正 Jar 包的分发参数,它既能保证环境随改随用,又能利用 YARN 进行分发。

相关推荐
OEC小胖胖9 小时前
02|从 `createRoot` 到 `scheduleUpdateOnFiber`:一次更新如何进入 React 引擎
前端·javascript·react.js·前端框架
林太白9 小时前
ofd文件
前端·后端
闲云一鹤9 小时前
Git 焚决!一个绝招助你找回丢失的代码文件!
前端·git
小宇的天下9 小时前
Calibre 3Dstack--每日一个命令day 6 [process和export layout](3-6)
java·前端·数据库
冴羽9 小时前
2025 年最火的前端项目出炉,No.1 易主!
前端·javascript·node.js
wordbaby9 小时前
Flexbox 布局中的滚动失效问题:为什么需要 `min-h-0`?
前端·css
demo007x9 小时前
在国内也能使用 Claude cli给自己提效,附实操方法
前端·后端·程序员
jayaccc9 小时前
Webpack配置详解与实战指南
前端·webpack·node.js
南囝coding9 小时前
发现一个宝藏图片对比工具!速度比 ImageMagick 快 6 倍,还是开源的
前端
前端小黑屋9 小时前
查看 Base64 编码的字体包对应的字符集
前端·css·字体