我目前有一个mapPartitions作业,它是flatMapping中的每个值 迭代器,我遇到了一个主要的GC成本问题 某些处决。有些遗嘱执行人需要20分钟,其中15分钟 纯垃圾收集,我相信很多都与垃圾收集有关 我正在输出的ArrayBuffer。有没有人对如何有任何建议 我可以做某种形式的流输出吗?
此外,是否有人对跟踪/寻址GC有任何建议 火花中的问题?
答案 0 :(得分:0)
请从Spark调整的官方页面参考以下文档。我希望它至少可以为您的分析提供指导:
内存管理概述 Spark中的内存使用情况大体上属于以下两类之一:执行和存储。执行内存是指用于洗牌,联接,排序和聚合中的计算的内存,而存储内存是指用于在集群中缓存和传播内部数据的内存。在Spark中,执行和存储共享一个统一的区域(M)。当不使用执行内存时,存储可以获取所有可用内存,反之亦然。如果有必要,执行可能会驱逐存储,但只有在总存储内存使用率下降到某个阈值(R)以下时,该存储才会退出。换句话说,R描述了M内的一个子区域,在该子区域中永远不会逐出缓存的块。由于实现的复杂性,存储可能无法驱逐执行。
此设计可确保几个理想的属性。首先,不使用缓存的应用程序可以将整个空间用于执行,从而避免了不必要的磁盘溢出。其次,确实使用缓存的应用程序可以保留最小的存储空间(R),以免其数据块被逐出。最后,这种方法可为各种工作负载提供合理的开箱即用性能,而无需用户了解内部如何分配内存。
尽管有两种相关的配置,但由于默认值适用于大多数工作负载,因此一般用户无需进行调整:
spark.memory.fraction将M的大小表示为(JVM堆空间-300MB)的一部分(默认值为0.6)。其余空间(40%)保留用于用户数据结构,Spark中的内部元数据,并在记录稀疏和异常大的情况下防止OOM错误。 spark.memory.storageFraction将R的大小表示为M的分数(默认值为0.5)。 R是M内的存储空间,其中的高速缓存块不受执行驱逐。 应该设置spark.memory.fraction的值,以便在JVM的旧版本或“长期使用”的一代中舒适地适应此堆空间量。有关详细信息,请参见下面有关高级GC调整的讨论。