Spark读取含BLOB字段的Oracle表写S3 Parquet时Executor内存问题
针对Spark读取含BLOB字段的Oracle表写入Parquet内存报错的解决方案
- 优化Parquet写入配置降低内存缓冲开销
- 调小Parquet块大小:将
parquet.block.size从默认128MB下调到16MB~32MB,减少单块需要缓冲的总数据量 - 调小Parquet页大小:设置
parquet.page.size为1MB,降低单页数据的内存占用 - 关闭BLOB字段字典编码:设置
spark.sql.parquet.enable.dictionary=false,高基数的BLOB字段使用字典编码只会额外占用内存,关闭后可大幅降低写入阶段内存开销 - 开启写入压缩:设置
spark.sql.parquet.output.compression.codec=snappy,压缩后的数据缓冲体积可降低30%~70%
- 调小Parquet块大小:将
- 读入后内部重分区,不占用额外Oracle连接
你之前调整的是读取阶段的numPartitions,受限于Oracle连接数无法调大,可以在读取完单分区数据后,调用repartition(N)将数据拆分为N个小分区,控制每个分区数据量在10万~20万条,拆分后每个Executor仅处理小批量数据,不会出现单分区内存过载问题 - 分段读取源表,分批写入
按表的主键、创建时间等可排序字段拆分查询范围,分多批次读取源表数据,每批次读取10万~20万条后直接写入S3,处理完一批释放一次内存,全程仅占用1个Oracle连接,符合源端连接限制 - 针对性调整Executor内存配置
针对该表单独调整任务资源配置,调大spark.executor.memory以及spark.executor.memoryOverhead,BLOB数据属于堆外内存开销较高的场景,默认堆外内存配额不足容易触发OOM,建议将堆外内存调整为正常配置的2~3倍
内容的提问来源于stack exchange,提问作者vishnu VIJAYAN
相关产品推荐
相关产品推荐

