为何我的spark-submit任务尝试多种配置仍在32核EC2上仅占用单核?
PySpark 单机跑满CPU核心的排障点
你的三类提交方案失效的核心原因
- 第一种不带master直接传executor参数的提交方式失效:
不指定--master参数时,Spark默认运行在local[1]单线程本地模式,该模式下不存在独立Executor进程,所有计算在驱动进程内完成,--executor-cores是Standalone/YARN/K8s这类集群模式的专属参数,本地模式下传了也完全不生效,自然无法调用多核心。 - 第二种指定
--master local[24]的提交方式失效:
最常见的漏项是PySpark脚本内硬编码了SparkSession配置。如果my_pyspark.py初始化SparkSession时写了类似.master("local[1]")的代码,这行硬编码会完全覆盖spark-submit命令行传入的所有master、核心数配置,直接把任务锁死在单核心模式。排查时直接删掉SparkSession构建逻辑里的.master()行,所有运行参数完全由提交命令传递即可。 - 第三种Standalone模式提交方式失效:
你只启动了Master调度进程,根本没启动Worker计算节点。没有Worker向Master注册可用的CPU、内存资源,Master根本没法给任务分配多核心的计算配额,任务只能退化为单线程在驱动进程里跑。正确的单机Standalone配置流程是:- 启动Master服务:
spark-class org.apache.spark.deploy.master.Master - 新开终端启动Worker,绑定到Master地址,给Worker分配足够的硬件资源:
spark-class org.apache.spark.deploy.worker.Worker spark://10.0.1.20:7077 --cores 30 --memory 100G - 等Worker正常注册到Master后,再提交带资源配置的任务,此时
--executor-cores 24这类参数才会被正常调度生效。
- 启动Master服务:
容易漏查的并行度限制项
就算核心参数全部配对,以下问题也会导致任务看起来只占用1个核心:
- 文件读取路径错误:如果Parquet读取路径误指向单个文件,而非存放6000个Parquet的父目录,Spark只会生成1个数据分区,自然只能用1个核处理。要确认读取路径是目标Parquet所在的根目录,不是单个文件路径。
- 分区数被硬编码限制:检查脚本和提交配置,确保没有设置
spark.sql.shuffle.partitions=1,可显式配置spark.sql.files.maxPartitionBytes=134217728(128MB),让Spark读取6MB的小Parquet时生成对应数量的并行分区,不要被默认配置合并成单分区。 - htop显示误判:htop默认隐藏进程内部的工作线程,多线程并发的Spark进程会被聚合显示为单进程占1个核心的CPU占用,可在htop界面按
H键切换为显示线程模式,确认实际CPU总占用率,避免把多线程跑满的状态误判为单核心运行。
内容的提问来源于stack exchange,提问作者Fabrice
相关产品推荐
相关产品推荐

