“每个核心一个执行程序与一个具有多个核心的执行程序”之间的区别

时间:2019-09-10 16:45:49

标签: apache-spark pyspark

我们知道每个任务同时在一个核心中执行。 可以说我们拥有具有此配置的节点集群:

10个节点。 每个节点16个核心。 每个节点64 GB RAM。

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

我的意思是:enter image description here VS enter image description here

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

预先感谢

3 个答案:

答案 0 :(得分:3)

1个具有16个核心的执行程序意味着您将拥有1个JVM,该JVM最多可以运行16个任务

具有1个CORE的16个执行程序意味着您将拥有16个JVM,并且每个JVM可以运行一个任务。

答案 1 :(得分:3)

我想添加到@dassum的答案中。还有更多要考虑的事情。

“ 1个具有16个核心的执行者”案例:

如果这些内核中的一项任务运行OOM或崩溃的方式不正确,则最多需要重新处理16个任务(及其祖先)(相比之下只有1个)。

“ 16个执行者,每个核心1个”案例:

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

答案 2 :(得分:3)

dassum的答案是绝对正确的,但要对此进行更深入的研究:

  • 与运行整个执行程序相比,任务的开销较低
  • 同一过程中的数据交换比不同过程之间的数据交换要快
  • 广播(例如,当您将一个很小的DataFrame连接到一个巨大的多分区的广播中时)将数据副本发送给每个执行者,因此执行者越多,必须完成的数据副本就越多

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

但是!

  • JVM不能在200GB以上的内存上正常运行-Cloudera文档建议64GB作为单个执行程序的内存限制,以限制垃圾回收问题
  • 如您所链接的文章中所述,HDFS几乎达到了5个内核的吞吐量限制,因此,如果您使用YARN运行群集,那是明智的限制

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