尽管 spark.executor.cores=1,Apache Spark 执行程序使用多个核心

Apache Spark executor uses more than one core despite of spark.executor.cores=1

当我在 CentOS 6.5 上启动 Apache Spark 1.2.1 应用程序时,根据 'top' 输出,我收到超过 100% 的执行程序负载,平均负载明显高于内核数量。

因此我的垃圾收集器负载很高。

类似的 Ubuntu 14.04 设置有 4 个物理内核 (Intel i5) 没有任何问题,每个执行器 1 个内核。

知道如何解决这个问题吗?

通过 System.setProperty 设置所有需要的属性的代码执行应用程序提交,然后创建 Spark 配置和上下文。它以相同的方式完成,唯一可能的区别可能是每个集群的 Spark 配置属性集,但没有什么特别的。在 Ubuntu 下,4 个核心 i5 这会导致适当的负载,每个执行程序使用的核心不超过 1 个。在 CentOS 6.5 和 2x6 内核 E5 下,我看到每个执行器使用了不止一个内核。另外,我试过给E5套用4核i5的配置,没有成功。

spark-defaults.conf 文件内容(在当前为 1.2.1 的 spark 版本替换之前):

spark.master=yarn-client
spark.eventLog.enabled=true
spark.eventLog.dir=hdfs:///user/spark/applicationHistory
spark.yarn.historyServer.address=X.X.X.X:18088
spark.executor.memory=1650M
spark.executor.cores=1
spark.cores.max=4
spark.executor.instances=15
spark.shuffle.memoryFraction=0.2
spark.storage.memoryFraction=0.02
spark.yarn.jar=hdfs:///user/spark/share/lib/${spark.version}/spark-assembly.jar

这里的主要问题是我发现 2 x 6 核 E5 的性能低于线性 1 i5 x 4 核。是的,E5 有点老,但无论如何应该更强大。然而,在两个集群上以类似负载分析了 Spark History 服务器 UI 我发现在 E5 集群上花在 GC 上的时间明显更多。疯狂状态。

您请求的执行器数量超过 CPU 个内核,如果您仔细想想,这应该是不可能的。然而,默认的 YARN 模型仅将 RAM 视为限制因素(使用 DefaultResourceCalculator ),并且它会很乐意在多个“1 核”执行程序之间共享 CPU 核,有效地导致负载优于 1 on CPU 核心。您可以使用 DominantresourceCalculator 来避免这种情况:)

好的,最后我发现:

  1. 其实我刚才对'CPU load'的理解有误。超过100%表示只有执行队列长度。
  2. CPU 内核分配正确。为每个执行程序分配了 1 个内核。
  3. 基于在 Spark 执行器上启用的 GC 分析,然后进行作业代码审查,发现根本原因只是某些对象的非最佳复制。代码已更正,在内存管理方面更加精简。

所以决议是:

When you see more than 100% load on CPU core under Spark executor you should first check your job GC logs for ineffective memory intensive operations or at least reduce lifetime of some objects by more aggressive release of resources.