“每个内核一个 Executor 与一个带有多个内核的 Executor”之间的区别

Ami*_*hou 3 apache-spark pyspark

我们知道每个任务当时都在一个核心中执行。假设我们有这样配置的节点集群:

10 节点。每个节点 16 个核心。每个节点 64 GB 内存。

我的问题是有 1 个 16 核的执行程序和 16 个 16 核的执行程序有什么区别???

我的意思是 :在此处输入图片说明 VS 在此处输入图片说明

我从这个来源得到启发:https : //spoddutur.github.io/spark-notes/distribution_of_executors_cores_and_memory_for_spark_application.html?fbclid=IwAR3xiFLBXBkwX2SrcJFZU0tfHU7Gssp-NJstfLDSRSRZzJgjK6ybYv

预先感谢

das*_*sum 8

1 个 16 核执行器意味着您将拥有 1 个 JVM,最多可以运行 16 个任务

16 个执行器和 1 个 CORE 意味着您将拥有 16 个 JVM,每个 JVM 可以运行一个任务。


Den*_*nko 7

我想补充@dassum 的答案。还有一些事情需要考虑。

“1个执行器16核”案例:

如果这些核心上的其中一个任务运行 OOM 或以不良方式崩溃,则需要重新处理多达 16 个任务(及其祖先)(而不是 1 个)。

“16 个执行器,每个执行器 1 个核心”情况:

内存中的数据缓存(persist())是每个执行器完成的。因此,对于设定的可用 RAM 总量,这意味着最多只能将 1/16 的内存分配给每个执行程序,并且大分区可能无法缓存在内存中,从而对处理速度产生负面影响。此外,其中一个执行程序更有可能运行 OOM,因为运行每个 JVM 实例都会产生相关开销,因此每个执行程序甚至可以使用这 1/16 的潜在可用 RAM 的一小部分。此外,执行者之间通常不会共享内存。因此,如果一个执行程序使用的内存不如另一执行程序那么多,则无法将内存分配给内存需求较高的执行程序。即内存分配效率较低。false除非spark.memory.offHeap.enabled 设置为true(默认设置为true)。


Dan*_*iel 5

dassum 的回答是绝对正确的,但要深入研究:

  • 任务的开销低于运行整个执行程序
  • 同一个进程内的数据交换比不同进程之间的数据交换更快
  • 广播(例如,当您将一个非常小的 DataFrame 加入一个巨大的多分区数据帧时)将数据副本发送到每个执行程序,因此执行程序越多,必须完成的数据副本就越多

因此,通过运行 16 个执行程序,每个执行程序具有一个内核,与 1 个具有 16 个内核的执行程序相比,您可能会看到性能下降。

然而!

  • JVM 不适用于 > 200GB 的内存 - Cloudera 文档建议将 64GB 作为单个执行程序的内存限制以限制垃圾收集问题
  • 如您链接的文章中所述,HDFS 几乎达到了 5 个内核的吞吐量限制,因此如果您使用 YARN 运行集群,这是合理的限制

在这种情况下,集群配置非常重要。除了数据分区之外,另一个关键因素是。最后,如果您的分区少于可用线程,您将不会利用所有集群,因为每个分区只能在一个线程中处理。另一个有趣的情况是,当您的分区数量比内核数量多时 - 假设分区大小大致相同,这将使您的处理时间加倍。