开发者概览
VeloxDynamicSizingOffheap
登录后可跨设备保存划线和私人笔记登录
动态堆外内存大小调整
Gluten 需要同时设置堆内和堆外内存大小,这会初始化不同的内存布局。若这些设置配置不当,可能导致性能下降。
为解决此问题,动态堆外内存大小调整是一项用于简化该过程的实验性功能。请注意,启用后,用户定义的 Spark 堆外内存设置(spark.memory.offHeap.enabled、spark.memory.offHeap.size)将不再生效,Velox 会将堆内内存大小作为其内存大小。要启用此功能,用户需要在 Spark 配置中添加如下配置项:
--conf spark.gluten.memory.dynamic.offHeap.sizing.enabled=true详细实现
要理解这些细节,首先需要掌握 JVM 内存管理的基础知识。关于 JVM 内部机制的资料有很多:
- https://exia.dev/blog/2019-12-10/JVM-Memory-Model/
- https://docs.oracle.com/cd/E13150\_01/jrockit\_jvm/jrockit/geninfo/diagnos/garbage\_collect.html
- https://www.scaler.com/topics/memory-management-in-java/
- https://developers.redhat.com/articles/2021/09/09/how-jvm-uses-and-allocates-memory#
- https://docs.oracle.com/en/java/javase/11/gctuning/factors-affecting-garbage-collection-performance.html
总体而言,该功能的工作方式如下:
- Spark 首先尝试基于堆内大小来分配内存。请注意,最大内存大小由
spark.executor.memory控制。 - 当 Velox 尝试分配内存时,Gluten 会尝试从系统内存中进行分配,并在内存分配器中记录该操作。
- 如果内存充足,分配将正常进行。
- 如果内存不足,Spark 会执行垃圾回收(GC)以释放堆内内存,从而让 Velox 能够分配内存。
- 如果 GC 之后内存仍然不足,Spark 会报告内存溢出(OOM)问题。
MaxHeapFreeRatio和MinHeapFreeRatio参数用于配置 Spark JVM 进程的最大/最小堆大小。请注意,这两个参数从 JDK-11 起才可用。
随后,我们会强制执行一个总内存配额,该配额等于 Java 堆中已提交(committed)和使用中(in-use)内存之和(通过 Runtime.getRuntime().totalMemory() 获取)加上 TreeMemoryConsumer 中跟踪的堆外内存。如果某次分配超过这个已提交的总内存,分配将失败并触发 OOM。
通过这一变更,“配额检查”会在 Gluten 收到内存分配请求时执行。实际上,这意味着即使堆外使用量已经足以导致分配失败,Java 代码仍可能在堆内配额范围内超额订阅内存。
局限性
该功能目前处于开发的初步阶段,将在后续更新中持续改进。
评论
登录后参与评论
正在加载评论…
KnowForge