Spark-land 中有几个相似但不同的概念,围绕如何将工作分配给不同的节点并同时执行。具体来说,有:
sparkDriverCount
)numWorkerNodes
)numExecutors
)dataFrame
)dataFrame
(numDFRows
)dataFrame
(numPartitions
)numCpuCoresPerWorker
)我相信所有 Spark 集群都有唯一一个Spark Driver,然后是 0+ 个工作节点。如果我错了,请先纠正我!假设我对此或多或少是正确的,让我们在这里锁定一些变量。假设我们有一个 Spark 集群,有 1 个 Driver 和 4 个 Worker 节点,每个 Worker 节点上有 4 个 CPU 核心(因此总共 16 个 CPU 核心)。所以这里的“给定”是:
sparkDriverCount = 1
numWorkerNodes = 4
numCpuCores = numWorkerNodes * numCpuCoresPerWorker = 4 * 4 = 16
鉴于这样的设置,我想知道如何确定一些事情。具体来说:
numWorkerNodes
和numExecutors
有什么关系?是否存在已知/普遍接受的工人与执行者比例?有没有办法在给定 numExecutors
(或任何其他输入)的情况下确定 numWorkerNodes
?numDFRows
与 numPartitions
比率?如何根据 dataFrame
的大小计算“最佳”分区数?numPartitions = numWorkerNodes * numCpuCoresPerWorker
,这是否属实?换句话说,它规定每个 CPU 核心应该有 1 个分区。和numWorkerNodes
有什么关系?numExecutors
一个worker可以托管多个执行器,您可以将其视为集群的机器/节点,将执行器视为在该worker上运行的进程(在核心中执行)。
所以 `numWorkerNodes <= numExecutors'.
他们有口粮吗?
就我个人而言,在一个假集群中工作,我的笔记本电脑是驱动程序,同一台笔记本电脑中的虚拟机是工作人员,和在超过 10k 节点的工业集群中,我不需要关心这一点,因为看起来 spark 可以解决这个问题。
我只是用:
--num-executors 64
当我启动/提交我的脚本时,我猜spark知道它需要召唤多少个工人(当然,还要考虑其他参数以及机器的性质)。
因此,就我个人而言,我不知道这样的比率。
是否存在已知/普遍接受/最佳的
与numDFRows
比率?numPartitions
我不知道其中的一个,但根据经验,你可以依靠 #executors 与 #executor.cores 的乘积,然后将其乘以 3 或 4。当然,这是一个启发式。在 pyspark 中,它看起来像这样:
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)
如何根据
的大小计算“最佳”分区数?DataFrame
这是一个很好的问题。当然,这很难回答,这取决于您的数据、集群等,但正如我与here所讨论的那样。
分区太少,您将拥有大量数据,尤其是在处理大数据时,从而使您的应用程序面临内存压力。
分区太多,您的 hdfs 将会承受很大的压力,因为随着分区数量的增加,必须从 hdfs 生成的所有元数据都会显着增加(因为它维护临时文件等)。 *
因此,您想要的也是找到分区数量的最佳位置,这是微调应用程序的部分之一。 :)
“经验法则”是:
,这是真的吗?numPartitions = numWorkerNodes * numCpuCoresPerWorker
啊,在看到这个之前我正在写上面的启发式。所以这个问题已经有了答案,但要考虑到 worker 和 executor 的区别。
* 今天我失败了:通过 Python 使用 Spark 准备我的大数据,当使用太多分区时导致活动任务在 Spark UI 中为负数。
实际上,存在某种启发式计算可以帮助您确定与数据集大小相关的所需核心数量。
它组成了 Spark 配置,分区大小(spark.sql.files.maxPartitionBytes),通常为 128M,它表示每个处理器要读取的数据集的字节数。
通常,如果您想在一次读取过程中读取整个数据集,您将需要
#cores = DatasetSize/maxPartitionBytes(均为 MB)
出于安全和成本原因,建议至少进行 3 次读取操作来读取大型数据集。所以公式变为:
#cores = DatasetSize/3/maxPartitionBytes(均为 MB)