根据worker,core和DataFrame大小确定Spark分区的最佳数量

sme*_*eeb 20 partitioning distributed-computing bigdata apache-spark spark-dataframe

Spark-land中有几个相似但又不同的概念,围绕着如何将工作分配到不同的节点并同时执行.具体来说,有:

  • Spark Driver节点(sparkDriverCount)
  • Spark群集可用的工作节点数(numWorkerNodes)
  • Spark执行器的数量(numExecutors)
  • 由所有工人/执行者同时操作的DataFrame(dataFrame)
  • dataFrame(numDFRows)中的行数
  • dataFrame(numPartitions)上的分区数
  • 最后,每个工作节点上可用的CPU核心数量(numCpuCoresPerWorker)

相信所有Spark集群都有一个且只有一个 Spark Driver,然后是0+个工作节点.如果我错了,请先纠正我!假设我或多或少是正确的,让我们在这里锁定一些变量.假设我们有一个带有1个驱动程序和4个工作节点的Spark集群,每个工作节点上有4个CPU核心(因此总共有16个CPU核心).所以这里的"给定"是:

sparkDriverCount = 1
numWorkerNodes = 4
numCpuCores = numWorkerNodes * numCpuCoresPerWorker = 4 * 4 = 16
Run Code Online (Sandbox Code Playgroud)

鉴于作为设置,我想知道如何确定一些事情.特别:

  • numWorkerNodes和之间有什么关系numExecutors?是否有一些已知/普遍接受的工人与遗嘱执行人的比例?有没有办法确定numExecutors给定numWorkerNodes(或任何其他输入)?
  • 是否已知/普遍接受/最佳比率numDFRowsnumPartitions?如何根据dataFrame?的大小计算"最佳"分区数?
  • 我从其他工程师那里得知,一般的"经验法则"是:numPartitions = numWorkerNodes * numCpuCoresPerWorker那有什么道理吗?换句话说,它规定每个CPU核心应该有一个分区.

gsa*_*ras 20

是的,一个应用程序只有一个驱动程序.

numWorkerNodes和之间有什么关系numExecutors

工作者可以托管多个执行程序,您可以将其视为工作组作为集群的机器/节点,执行程序是作为该工作程序上运行的进程(在核心中执行).

所以`numWorkerNodes <= numExecutors'.

他们有什么口粮吗?

就个人而言,在一个假的集群,在那里我的笔记本电脑是非常相同的笔记本电脑的驱动程序和虚拟机是工人工作过,在> 10K节点的产业集群,我并不需要关心的是,因为它似乎照顾到了这一点.

我只是用:

--num-executors 64
Run Code Online (Sandbox Code Playgroud)

当我启动/提交我的脚本时,知道,我想,它需要召唤多少工人(当然,还要考虑其他参数,以及机器的性质).

因此,就个人而言,我不知道这样的比例.


是否已知/普遍接受/最佳比率numDFRowsnumPartitions

我不知道一个,但根据经验,你可以依靠#executor.cores的#executors产品,然后将它乘以3或​​4.当然这是一种启发式方法.在它看起来像这样:

sc = SparkContext(appName = "smeeb-App")
total_cores = int(sc._conf.get('spark.executor.instances')) * int(sc._conf.get('spark.executor.cores'))
dataset = sc.textFile(input_path, total_cores * 3)
Run Code Online (Sandbox Code Playgroud)

如何根据DataFrame?的大小计算"最佳"分区数?

这是一个很好的问题.当然,它很难回答,它取决于你的数据,集群等,但作为讨论这里与自己.

分区太少,您将拥有大量数据,尤其是当您处理,这会使您的应用程序处于内存压力.

太多的分区,你的会有很大的压力,因为必须从生成的所有元数据随着分区数量的增加而显着增加(因为它维护临时文件等).*

所以你想要的也是找到分区数量的最佳位置,这是微调你的应用程序的一部分.:)

"经验法则"是:numPartitions = numWorkerNodes * numCpuCoresPerWorker是真的吗?

啊,在看到这个之前,我正在编写上面的启发式.所以这已经得到了回答,但考虑到了工人遗嘱执行人的区别.


*我今天刚刚失败了:当使用太多分区时,使用Spark通过Spark准备我的bigdata导致Active任务在Spark UI中是负数.

  • 如果“numPartitions”仅由“numWorkerNodes”和“numCpuCoresPerWorker”决定,则与“numDFRows”无关,这意味着如果输入数据集很大,则分区大小也很大。最终会导致OOM问题。不是吗? (2认同)