gpt4 book ai didi

hadoop - 驱动程序内存、执行程序内存、驱动程序内存开销和执行程序内存开销对作业运行成功的 Apache Spark 影响

转载 作者:IT王子 更新时间:2023-10-28 23:29:12 25 4
gpt4 key购买 nike

我正在 YARN 上对我的 Spark 作业进行一些内存调整,我注意到不同的设置会产生不同的结果并影响 Spark 作业运行的结果。但是,我很困惑,不完全理解为什么会发生这种情况,如果有人可以为我提供一些指导和解释,我将不胜感激。

我将提供一些背景信息并发布我的问题并描述我在下面遇到的案例。

我的环境设置如下:

  • 内存 20G,每个节点 20 个 VCore(共 3 个节点)
  • Hadoop 2.6.0
  • Spark 1.4.0

我的代码递归过滤 RDD 以使其更小(作为算法的一部分删除示例),然后执行 mapToPair 和 collect 以收集结果并将它们保存在列表中。

问题

  1. 为什么在第一种情况和第二种情况之间会抛出不同的错误并且作业运行时间更长(对于第二种情况),而只增加了执行程序内存?这两个错误是否以某种方式联系在一起?

  2. 第三种和第四种情况都成功了,我明白这是因为我提供了更多的内存来解决内存问题。但是,在第三种情况下,

spark.driver.memory + spark.yarn.driver.memoryOverhead = the memory that YARN will create a JVM

= 11g + (driverMemory * 0.07, with minimum of 384m) = 11g + 1.154g = 12.154g

因此,从公式中,我可以看到我的工作需要 MEMORY_TOTAL 大约 12.154g 才能成功运行,这解释了为什么我需要超过 10g 的驱动程序内存设置。

但是对于第四种情况,

spark.driver.memory + spark.yarn.driver.memoryOverhead = the memory that YARN will create a JVM

= 2 + (driverMemory * 0.07, with minimum of 384m) = 2g + 0.524g = 2.524g

似乎只需将内存开销增加少量 1024(1g) 就可以成功运行作业,驱动程序内存仅为 2g,MEMORY_TOTAL 仅为 2.524g !而没有开销配置,小于 11g 的驱动程序内存会失败,但从公式中没有意义,这就是我感到困惑的原因。

为什么增加内存开销(对于驱动程序和执行程序)可以让我的工作以较低的MEMORY_TOTAL(12.154g 与 2.524g)成功完成?我还缺少其他一些内部工作吗?

第一种情况

/bin/spark-submit --class <class name> --master yarn-cluster --driver-memory 7g --executor-memory 1g --num-executors 3 --executor-cores 1 --jars <jar file>

如果我使用任何小于 11g 的驱动程序内存运行我的程序,我将收到以下错误,即 SparkContext 正在停止或类似的错误,即在停止的 SparkContext 上调用方法。根据我收集的信息,这与内存不足有关。

DriverMemory-7g_ExecutorMemory-1g

第二种情况

/bin/spark-submit --class <class name> --master yarn-cluster --driver-memory 7g --executor-memory 3g --num-executors 3 --executor-cores 1 --jars <jar file>

如果我使用相同的驱动程序内存但更高的执行程序内存运行程序,则作业运行时间比第一种情况更长(大约 3-4 分钟),然后它会遇到与之前不同的错误,即容器请求/使用超过允许的内存,因此被杀死。虽然我觉得这很奇怪,因为执行器内存增加了,并且发生了这个错误而不是第一种情况下的错误。

DriverMemory-7g_ExecutorMemory-3g

第三种情况

/bin/spark-submit --class <class name> --master yarn-cluster --driver-memory 11g --executor-memory 1g --num-executors 3 --executor-cores 1 --jars <jar file>

驱动程序内存大于 10g 的任何设置都将导致作业能够成功运行。

第四种情况

/bin/spark-submit --class <class name> --master yarn-cluster --driver-memory 2g --executor-memory 1g --conf spark.yarn.executor.memoryOverhead=1024 --conf spark.yarn.driver.memoryOverhead=1024 --num-executors 3 --executor-cores 1 --jars <jar file>

使用此设置,作业将成功运行(驱动程序内存 2g 和执行程序内存 1g,但会增加驱动程序内存开销(1g)和执行程序内存开销(1g)。

任何帮助都将不胜感激,并且对我对 Spark 的理解很有帮助。提前致谢。

最佳答案

您的所有案例都使用

--executor-cores 1

最好超过 1。不要超过 5。根据我们的经验和 Spark 开发人员的建议。

例如 http://blog.cloudera.com/blog/2015/03/how-to-tune-your-apache-spark-jobs-part-2/:

A rough guess is that at most five tasks per executor 
can achieve full write throughput, so it’s good to keep
the number of cores per executor below that number

我现在找不到推荐每个执行程序超过 1 个内核的引用。但想法是在同一个执行程序中运行多个任务使您能够共享一些公共(public)内存区域,因此它实际上可以节省内存。

从 --executor-cores 2 开始,双倍 --executor-memory (因为 --executor-cores 还告诉一个执行器将同时运行多少个任务),看看它对你有什么作用。就可用内存而言,您的环境是紧凑的,因此使用 3 或 4 会为您提供更好的内存利用率。

我们使用 Spark 1.5 并在很久以前停止使用 --executor-cores 1,因为它会产生 GC 问题;它看起来也像一个 Spark 错误,因为仅仅提供更多内存并没有像切换到每个容器有更多任务那样有帮助。我猜同一执行器中的任务可能会在不同时间达到其内存消耗的峰值,因此您不必浪费/不必为了使其工作而过度配置内存。

另一个好处是,Spark 的共享变量(累加器和广播变量)每个执行程序只有一个副本,而不是每个任务——因此,每个执行程序切换到多个任务可以直接节省内存。即使您没有明确使用 Spark 共享变量,Spark 也很可能会在内部创建它们。例如,如果您通过 Spark SQL 连接两个表,Spark 的 CBO 可能会决定广播一个较小的表(或较小的数据帧)以使连接运行得更快。

http://spark.apache.org/docs/latest/programming-guide.html#shared-variables

关于hadoop - 驱动程序内存、执行程序内存、驱动程序内存开销和执行程序内存开销对作业运行成功的 Apache Spark 影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32292414/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com