使用Microsoft Azure,我有一个包含2个主节点和50个工作节点的集群。所有节点都有8个内核和64 GB RAM。
我正在使用pyspark运行spark-submit作业。我的Python代码中最相关的部分是我创建长度为72的元组的Python列表arg_list
。(每个元组有大约6个元素,没有两个元组是相同的。)然后我创建一个包含72个分区的RDD像这样,
sc = spark.sparkContext
rdd = sc.parallelize(arg_list, len(arg_list))
我的目标是同时处理所有72个分区。处理分区涉及以下内容:
gensim
的Python包,使用读取的两个文件的内容执行NLP任务。为此,我按照以下方式提交我的spark提交作业,
spark-submit --master yarn --num-executors 100 --executor-cores 3 --executor-memory 19G /path/to/my/file.py
思路如下。将每个工作节点用于2个执行程序。每个执行器都有3个内核,因此每个节点有8-2 * 3 = 2个内核,用于节点管理器和任何其他开销任务。由于每个节点可以获得2个执行程序,并且我有50个节点,因此我获得了100个执行程序。 (我承认在这种情况下群集比需要的要大一些。)
当我运行此代码时,我可以使用Ambari监视工作节点的活动。我原本预计72/2 = 36个工作节点忙(正如平均负载所证明)和50-36 = 14个节点空闲。相反,我看到只有12个节点正忙,并且每个节点似乎正在运行6个进程。
6 * 12 = 72,任务数量可能不是巧合。好像Spark / YARN决定忽略我的参数,并将我的分区处理尽可能少的节点。
我还注意到,完成72个任务中的任何一个似乎需要很长时间。基于看到一个典型的任务在串行模式下运行需要3个小时并且看到我的Spark作业运行6个小时而根本没有输出时,我说这个。
问题:
我已经阅读了关于spark-submit / Yarn参数的指南,并认为我写的内容很有意义。我还缺少一些额外的参数设置吗?
答案 0 :(得分:1)
Spark会处理每个分区,具体取决于您正在运行的作业可用的核心总量。
让我们说你的火花工作有100个执行器,每个执行器有3个核心。这意味着您可以同时处理100 x 3 = 300个分区,假设spark.task.cpus
设置为1。
spark.task.cpus
是为每个任务分配的核心数,--executor-cores
指定每个执行者的核心数。
具有2个执行程序的工作节点,处理2 x 3 = 6个分区。默认spark.default.parallelism = 12.所以6x12 = 72。
Spark中用于在运行时调整分区数的两个配置属性如下:
按
增加默认并行度--conf spark.default.parallelism=36 --conf spark.default.parallelism=36
设置spark.task.cpus=2
和--executor-cores 4
(在spark submit命令中)。因此每个节点仅处理(4/2 =)2个分区。在这种情况下,36个节点将用于并行处理数据。