You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DataBricks内存未释放问题:根源排查与解决方法咨询

Azure Databricks读取海量嵌套JSON数据后内存无法释放的问题

环境与场景

  • 平台:Azure DataBricks 12.2 LTS(内置Apache Spark 3.3.2、Scala 2.12)
  • 计算节点:Standard_DS5_v2
  • 问题:从Delta表读取含大量嵌套JSON的海量数据,执行代码后Ganglia集群面板显示内存未释放,已尝试df.unpersist()、del df、df=None配合gc.collect()均无效。

执行代码

df_spark = spark.sql(my_qyery_to_delta_table)
df_pandas = df_spark.toPandas()
df_spark.unpersist()

import gc
del df_pandas
del df_spark
gc.collect()

问题根源

  1. Spark自动缓存残留:Spark SQL执行时会自动缓存查询结果(尤其是涉及Shuffle或重复执行的场景),单个DataFrame的unpersist()无法清理所有Spark层面的缓存数据,导致JVM内存占用未释放。
  2. Python与JVM内存隔离:toPandas()将Executor端数据全量拉取到Driver节点的Python进程中,嵌套JSON结构生成的复杂Python对象可能存在隐式引用(如Spark内部元数据关联),Python GC无法彻底回收;同时Spark的JVM层面内存需要JVM自身GC回收,Python的gc.collect()无法触发JVM GC。
  3. Driver节点内存泄漏:Notebook环境中,之前单元格的变量引用、Spark会话残留资源可能导致内存无法回收,嵌套JSON的复杂结构会加剧此类问题。
  4. Ganglia统计延迟:Ganglia内存指标存在一定统计延迟,若长时间未下降则属于内存未实际释放。

解决方法

  • 清理全量Spark缓存:执行spark.catalog.clearCache()替代单个DataFrame的unpersist(),彻底清除Spark层面所有缓存的表和DataFrame数据。
  • 触发JVM层面GC:通过Python调用JVM的GC机制,执行spark.sparkContext._jvm.System.gc(),强制回收JVM占用的内存。
  • 优化数据拉取逻辑:在Spark层面先做过滤、聚合或字段裁剪,减少toPandas()拉取到Driver的数据量;若不需要全量数据,优先使用limit()或采样操作缩小数据规模。
  • 关闭Spark自动缓存:在Notebook开头添加配置spark.conf.set("spark.sql.cache.enabled", "false"),禁止Spark自动缓存查询结果,避免不必要的内存占用。
  • 隔离测试环境:在全新的Notebook中单独执行代码,避免之前单元格的变量引用干扰内存回收。
  • 调整Driver内存配置:若Driver节点内存长期不足,可在集群配置中增大spark.driver.memory值,或配合升级节点规格(如使用更大的DS系列节点)。

内容的提问来源于stack exchange,提问作者RunTheGauntlet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 19:06:19