com.crealytics.spark.excel与pandas/awswrangler读取S3大Excel对比问题
com.crealytics.spark.excel读取大Excel OOM问题分析与性能差异对比
一、com.crealytics.spark.excel可能存在的操作失误
- 未启用分批读取参数:spark-excel默认会将整个Excel文件加载到单个Executor的内存中,不管集群有多少worker,大文件都会直接撑爆单节点内存。需手动添加
maxRowsInMemory参数限制单次加载的行数,或者通过chunkSize(部分版本支持)实现分批读取;如果Excel中有可用于分区的列,也可配置partitionColumn让Spark拆分任务到多个Executor。 - 依赖自动Schema推断:自动推断Schema需要加载全量数据到内存分析字段类型,150MB的Excel会在此阶段直接耗尽内存。必须手动指定Schema(比如用
StructType定义字段),关闭自动推断(inferSchema=False)。 - 未调整JVM堆内存配置:AWS Glue默认worker的Executor内存不足以承载大Excel的内存开销,即使增加worker数量,单Executor的内存瓶颈依然存在。需在Glue作业配置中添加
--conf spark.executor.memory=16g --conf spark.driver.memory=16g这类参数,提升单个Executor的堆内存上限。
二、两者工作机制的核心差异
com.crealytics.spark.excel的局限性
- 分布式能力无法充分发挥:Excel是单文件非列式存储格式,spark-excel基于Java的POI库实现,无法像读取Parquet、CSV那样拆分文件并行处理,默认只能将整个文件分配给单个Executor处理——你扩容到20-30个worker时,只有1个在干活,其余全闲置,资源完全浪费。
- POI的内存开销极高:POI默认采用「用户模式」读取Excel,会把整个文档的DOM结构加载到内存,内存占用通常是文件大小的5-10倍(150MB文件可能需要1.5GB以上内存),远超Glue默认Executor的内存配额,必然触发OOM。
pandas/awswrangler的高效逻辑
- 流式/分块读取:awswrangler封装的pandas
read_excel使用openpyxl/xlrd的只读模式,会逐行或按指定块大小读取数据,无需将整个文件加载到内存,内存占用仅为当前处理块的大小,大幅降低内存压力。 - 真正的分布式利用:在多worker环境下,awswrangler可以将大Excel文件按行范围拆分,分配给不同worker并行处理,充分利用集群资源——4个worker同时干活,自然比单Executor硬扛效率高得多。
总结
如果要继续使用spark-excel适配现有流水线,需严格调整上述参数(手动Schema、分批读取、调大Executor内存),但本质上Spark对单大文件Excel的处理天生存在局限性;而pandas/awswrangler针对Excel格式的读取优化更彻底,且能有效利用分布式资源,更适合处理50-150MB级别的大Excel文件。
内容的提问来源于stack exchange,提问作者Hamza E. Khan
相关产品推荐
相关产品推荐

