PySpark读取大Parquet文件触发Illegal Capacity: -102错误如何解决
Spark 读取Parquet文件触发行动算子报Illegal Capacity: -102 问题排查与解决
java.lang.IllegalArgumentException: Illegal Capacity: -102本质是Spark解析Parquet文件的元数据或数据块时,读取到的块大小数值为负数,超出了缓冲区初始化的合法容量范围。由于spark.read.parquet属于懒加载的转换算子,仅会读取最基础的元数据不会实际解析数据,所以执行时不会报错,只有触发行动算子实际加载数据时才会抛出异常。
排查步骤
- 校验Parquet文件完整性
首先确认文件是否为传输中断、写入失败生成的损坏文件,可通过parquet-tools meta path/to/file.parquet命令直接校验文件元数据合法性;如果没有对应工具,也可先在Spark读取时添加mergeSchema=false参数测试:
如果添加参数后可以正常执行操作,说明是多文件Schema合并时读取异常元数据导致的问题。df = spark.read.option("mergeSchema", "false").parquet("path/to/file.parquet") - 检查Parquet文件写入配置合法性
该错误高发于Parquet文件生成时配置错误,比如行组大小、压缩块大小被误设为负数,或者数据页损坏。你可以先执行df.printSchema(),如果打印Schema就直接报错,说明文件元数据已经损坏,需要重新生成源文件。 - 验证Spark版本兼容性
低版本Spark 2.x读取Spark 3.x生成的带自定义元数据的Parquet文件,或反向读取时,都可能出现该兼容性问题,可尝试添加以下读取参数临时兼容:df = spark.read.option("parquet.enable.dictionary", "false")\ .option("parquet.read.support.class", "org.apache.parquet.hadoop.ParquetReadSupport")\ .parquet("path/to/file.parquet") - 排查目录下的无效文件
如果读取路径是多文件目录,检查目录下是否存在空文件、非Parquet后缀的无效文件,可先指定读取单个小分片文件测试,排除单个分片损坏拉低整体读取的问题。
通用解决方法
- 确认是文件损坏的场景,重新生成或拉取源Parquet文件即可解决
- 兼容性问题场景,优先统一读写端的Spark版本、Parquet依赖版本,也可临时使用上文的读取参数规避
- Schema合并异常场景,可手动指定Schema读取,跳过Spark自动推断Schema的步骤,示例如下:
from pyspark.sql.types import StructType, StructField, StringType, IntegerType # 替换为你的Parquet文件实际Schema custom_schema = StructType([ StructField("col1", StringType(), nullable=True), StructField("col2", IntegerType(), nullable=True) ]) df = spark.read.schema(custom_schema).parquet("path/to/file.parquet")
内容的提问来源于stack exchange,提问作者NaWeeD
相关产品推荐
相关产品推荐

