Spark:每个执行者的内核对应用程序运行时没有影响

Spark: No effect of cores per executors on application runtime

我正在测试每个执行程序的不同内核数 (--executor-cores) 对 SVD on Spark 的 运行 时间的影响。随着 --executor-cores 固定,主数据 RDD 的分区数会发生变化。但是,对于给定数量的 RDD 分区,不同 --executor-cores 的 SVD 计算时间似乎没有显着变化。这有点令人困惑。

我的环境是:

我已经绘制了 --executor-cores = [4, 16] 的结果,正如您所看到的,对于给定的分区大小,当分区大小增加时,计算时间之间没有太大差异。所以我的问题是:

一般来说,每个执行器的最佳内核平衡因工作负载而异;虽然每个执行器的核心数通常会减少每个执行器的开销,但还有一些其他因素会影响性能与每个执行器的核心数成反比,主要是围绕进程全局共享资源和争用瓶颈:

  1. 垃圾回收;同一进程 space 中的任务现在在内存 allocation/garbage-collection 期间相互影响更大,成为共享争用瓶颈。
  2. 当使用大量线程时,HDFS 客户端等共享客户端可能会出现争用问题。
  3. 像 akka 线程这样的共享池可能会因进程中的并发任务过多而超额订阅。
  4. 任何需要同步的共享数据结构都意味着更多的时间花费在线程上下文切换和等待锁上;这包括 metrics reporting

另一方面,为每个执行程序添加更多内核的好处包括:

  1. 减少每个执行程序的内存开销;如果每个任务需要一定数量的内存,理论上与许多小型执行器相比,您可以将更多并发任务打包到具有单个非常大的执行器的机器上。
  2. 共享内存 space 成为 broadcast variables/data.
  3. 之类的一大优势

this Cloudera blog post.

中解释了很多这些权衡和具体数字,特别是关于过大执行器的缺点。

在分区数量较少的情况下,理论上分区数量少于执行器数量,只要任务分散,性能应该更好或等于较大的执行器在每种情况下,同样好地进入不同的执行者。但是,如果打包任务将它们全部放在一个执行器上,那么它只取决于工作量; shuffle-heavy 的东西可能会受益于这样一个事实,即所有的进程都是本地的,但 HDFS I/O-heavy 的东西会受到争用。