我正在运行spark on yarn。我不明白下面的设置spark.yarn.executor.memoryOverhead和spark.memory.offHeap.size之间有什么区别。这两个设置似乎都是为spark执行器分配堆外内存的设置。我应该使用哪一个?还有,对于executor堆外内存的推荐设置是什么?非常感谢!
spark.yarn.executor.memoryOverhead
spark.memory.offHeap.size
p4rjhz4m1#
**TL;DR:**对于Spark 1.x和2.x,总堆外内存= spark.executor.memoryOverhead(其中包括spark.offHeap.size)对于Spark 3.x,总堆外内存= spark.executor.memoryOverhead + spark.offHeap.size(this page的贷记)
spark.executor.memoryOverhead
spark.offHeap.size
详细说明:spark.executor.memoryOverhead由YARN等资源管理使用,而spark.memory.offHeap.size由Spark内核(内存管理器)使用。
Spark 2.4.5及之前版本:
spark.executor.memoryOverhead应包含spark.memory.offHeap.size。这意味着如果指定offHeap.size,则需要手动将此部分添加到YARN的memoryOverhead中。从YarnAllocator.scala的以下代码中可以看到,当YARN请求资源时,它并不了解offHeap.size的任何信息:
offHeap.size
memoryOverhead
private[yarn] val resource = Resource.newInstance( executorMemory + memoryOverhead + pysparkWorkerMemory, executorCores)
但是,Spark 3.0中的行为发生了变化:
spark.executor.memoryOverhead不再包含spark.memory.offHeap.size。YARN将在请求资源时为您包含offHeap.size。从新的documentation:注意:额外的内存包括PySpark执行器内存(当spark.executor.pyspark.memory未配置时)和在同一容器中运行的其他非执行器进程使用的内存。运行执行器的容器的最大内存大小由spark.executor.memoryOverhead、spark.executor.memory、spark.memory.offHeap.size和spark. executor. pyspark. memory的总和决定。从code还可以看出:
private[yarn] val resource: Resource = { val resource = Resource.newInstance( executorMemory + executorOffHeapMemory + memoryOverhead + pysparkWorkerMemory, executorCores) ResourceRequestHelper.setResourceRequests(executorResourceRequests, resource) logDebug(s"Created resource capability: $resource") resource }
有关此更改的更多详细信息,请参阅this Pull Request。对于您的第二个问题,executor offheap memory的建议设置是什么?这取决于您的应用程序,您需要进行一些测试。我发现this页面有助于进一步解释它:堆外内存是减少GC暂停的一个很好的方法,因为它不在GC的作用域中。但是,它带来了序列化和反序列化的开销。反序列化又使得堆外数据有时可以放在堆内存中,从而暴露给GC。此外,Project Tungsten带来的新数据格式这两个原因使得在ApacheSpark应用程序中使用堆外内存应该仔细规划,特别是经过测试的。顺便说一句,spark.yarn.executor.memoryOverhead已被弃用并更改为spark.executor.memoryOverhead,这是YARN和Kubernetes的常见版本。
7hiiyaii2#
https://spark.apache.org/docs/1.2.0/running-on-yarn.html
https://spark.apache.org/docs/2.4.4/configuration.html
2条答案
按热度按时间p4rjhz4m1#
**TL;DR:**对于Spark 1.x和2.x,总堆外内存=
spark.executor.memoryOverhead
(其中包括spark.offHeap.size)对于Spark 3.x,总堆外内存=spark.executor.memoryOverhead
+spark.offHeap.size
(this page的贷记)详细说明:
spark.executor.memoryOverhead
由YARN等资源管理使用,而spark.memory.offHeap.size
由Spark内核(内存管理器)使用。Spark 2.4.5及之前版本:
spark.executor.memoryOverhead
应包含spark.memory.offHeap.size
。这意味着如果指定offHeap.size
,则需要手动将此部分添加到YARN的memoryOverhead
中。从YarnAllocator.scala的以下代码中可以看到,当YARN请求资源时,它并不了解offHeap.size
的任何信息:但是,Spark 3.0中的行为发生了变化:
spark.executor.memoryOverhead
不再包含spark.memory.offHeap.size
。YARN将在请求资源时为您包含offHeap.size
。从新的documentation:注意:额外的内存包括PySpark执行器内存(当spark.executor.pyspark.memory未配置时)和在同一容器中运行的其他非执行器进程使用的内存。运行执行器的容器的最大内存大小由spark.executor.memoryOverhead、spark.executor.memory、spark.memory.offHeap.size和spark. executor. pyspark. memory的总和决定。
从code还可以看出:
有关此更改的更多详细信息,请参阅this Pull Request。
对于您的第二个问题,executor offheap memory的建议设置是什么?这取决于您的应用程序,您需要进行一些测试。我发现this页面有助于进一步解释它:
堆外内存是减少GC暂停的一个很好的方法,因为它不在GC的作用域中。但是,它带来了序列化和反序列化的开销。反序列化又使得堆外数据有时可以放在堆内存中,从而暴露给GC。此外,Project Tungsten带来的新数据格式这两个原因使得在ApacheSpark应用程序中使用堆外内存应该仔细规划,特别是经过测试的。
顺便说一句,
spark.yarn.executor.memoryOverhead
已被弃用并更改为spark.executor.memoryOverhead
,这是YARN和Kubernetes的常见版本。7hiiyaii2#
spark.yarn.executor.memoryOverhead
用于StaticMemoryManager。这在较早的Spark版本(如1.2)中使用。要为每个执行器分配的堆外内存量(MB)。这是用于VM开销、驻留字符串、其他本机开销等的内存。它往往随执行器大小而增长(通常为6-10%)。
您可以在较早的Spark文档(如Spark1.2文档)中找到这一点:
spark.memory.offHeap.size
用于UnifiedMemoryManager,1.6版之后默认使用可用于堆外分配的绝对内存量(以字节为单位)。此设置对堆内存使用没有影响,因此,如果执行程序的总内存消耗必须在某个硬限制内,请确保相应地收缩JVM堆大小。当spark.memory.offHeap.enabled=true时,此值必须设置为正值。
您可以在最新的Spark文档(如Spark2.4文档)中找到这一点: