我正在努力让我的Spark程序避免超过YARN内存限制(在执行器上)。
我遇到的“已知”错误是:
Container killed by YARN for exceeding memory limits. 3.8 GB of 3.6 GB physical memory used.
我希望不仅仅提高执行器内存、执行器内存开销或调整我的资源或分区,我想知道为什么我的堆外内存总是在增长。
我正在使用 pyspark v2.4.4
,据我所知 YARN 内存开销(对于执行器)是由 Spark 程序分配的任何堆外内存(JVM 之外)。
我唯一知道的额外的“非相关”的堆外内存是 Python 内存,它不是 Spark 的内存开销的一部分 documentation:
我在程序中使用了大量缓存;禁用运行执行器的容器的最大内存大小取决于 spark.executor.memoryOverhead、spark.executor.memory、spark.memory.offHeap.size 和 spark.executor.pyspark.memory 的总和。
persist
调用可以在某种程度上解决内存开销问题(减少执行器死亡,最终使程序完成),但由于此数据应仅在JVM /磁盘中由UnifiedMemoryManager管理,因此不应使用任何堆外内存。由于默认情况下禁用了堆外模式(
spark.memory.offHeap.use
),哪些情况可能导致内存开销增加,为什么禁用程序中的缓存有助于减少开销大小?
编辑使用更大的执行器(两倍的内存和核心)也可以解决这个问题。
当JVM的内存更大时,开销更大是有道理的(大于386m时增加10%),但我们仍然在此JVM上使用了2个核心(即2个任务),并且我不明白在哪些情况下会增加内存开销。