Databricks集群8GB仍遇BufferHolder错误,求原因与解决方法
PySpark拆分大型JSON时BufferHolder大小超限错误的原因与解决办法
错误场景与信息
在Databricks运行PySpark拆分大型JSON文件时,触发如下错误:
Caused by: java.lang.IllegalArgumentException: Cannot grow BufferHolder by size 8 because the size after growing exceeds size limitation 2147483632
使用的代码如下:
from pyspark.sql.functions import explode, col import itertools # Read the JSON file from Databricks storage df_json = spark.read.option("multiline","true").json("/mnt/BigData_JSONFiles/2022-10_040_05C0_in-network-rates_2_of_2.json") spark.conf.set("spark.sql.execution.arrow.pyspark.enabled", "false") df_network=df_json.select(df_json.columns[1:]) df_version=df_json.select(df_json.columns[:1]) df_network.write.format("json").save("/mnt/BigData_JSONFiles/2022-10_040_05C0_in-network-rates_2_of_2_detail.json") df_version.write.format("json").save("/mnt/BigData_JSONFiles/2022-10_040_05C0_in-network-rates_2_of_2_header.json") display(df_network) display(df_version)
错误原因
该错误核心是单条数据对象的内存占用突破了Spark BufferHolder的2GB上限(2147483632字节约等于2^31-8,接近2GB)。由于使用multiline=true模式读取大型JSON,整个文件会被解析为单个分区内的单条记录,这条记录包含了所有数据,内存占用直接超出BufferHolder的限制,导致内存分配失败。
解决办法
1. 优化JSON读取逻辑,分散单条记录内存压力
- 如果目标JSON是数组格式,移除
multiline=true参数,让Spark自动将数组内每个元素拆分为独立记录,避免单条记录过大。 - 若必须使用
multiline模式,提前将大型JSON拆分为多个小文件(比如通过Databricks文件操作工具或Linuxsplit命令),再分批读取处理。
2. 调整Spark内存配置
- 增大Executor和Driver的内存配额,示例代码:
spark.conf.set("spark.executor.memory", "8g") spark.conf.set("spark.driver.memory", "4g") - 启用堆外内存存储,缓解堆内内存压力:
spark.conf.set("spark.sql.columnVector.offheap.enabled", "true") spark.conf.set("spark.memory.offHeap.size", "4g")
3. 优化数据拆分与存储逻辑
- 先拆分嵌套大字段(比如用
explode展开数组类型字段),将单条大记录拆分为多条小记录后,再执行select和保存操作。 - 保存数据时,通过
repartition或coalesce调整分区数,避免单个分区数据量过载:df_network.repartition(8).write.format("json").save("/mnt/BigData_JSONFiles/2022-10_040_05C0_in-network-rates_2_of_2_detail.json")
4. 保持关闭Arrow优化
你已经设置spark.sql.execution.arrow.pyspark.enabled=false,该配置会避免Arrow内存聚合带来的额外压力,保持即可。
内容的提问来源于stack exchange,提问作者anjaney shrivastav
相关产品推荐
相关产品推荐

