spark读取parquet数据报异常: java.lang.NegativeArraySizeException

背景: 在执行spark任务的时候,中间有多次落盘,将数据以parquet格式写到hdfs。然后再将数据读取出来继续执行。执行到中间有如下报错:

 

	[spark] Caused by: org.apache.parquet.io.ParquetDecodingException: Can not read value at 0 in block -1 in file hdfs://master1:8020/user/xxx/part-00512-0462dbf5-98b2-41fa-925c-3ab53f9f060b-c000.snappy.parquet
	[spark]         at org.apache.parquet.hadoop.InternalParquetRecordReader.nextKeyValue(InternalParquetRecordReader.java:223)
	[spark]         at org.apache.parquet.hadoop.ParquetRecordReader.nextKeyValue(ParquetRecordReader.java:215)
	[spark]         at org.apache.spark.sql.execution.datasources.RecordReaderIterator.hasNext(RecordReaderIterator.scala:39)
	[spark]         at org.apache.spark.sql.execution.datasources.FileScanRDD$$anon$1.hasNext(FileScanRDD.scala:106)
	[spark]         at org.apache.spark.sql.execution.datasources.FileScanRDD$$anon$1.nextIterator(FileScanRDD.scala:182)
	[spark]         at org.apache.spark.sql.execution.datasources.FileScanR
在使用 Parquet 输出时遇到 `Unsupported output type: NULL` 错误,通常表明在写入数据到 Parquet 文件时,某个字段的值为 `NULL`,而该字段在 Parquet schema 中被定义为不可为空(required),导致写入失败。 Parquet 文件格式要求字段在写入前具有明确的类型定义。如果某个字段的值为 `NULL`,但该字段在 schema 中被定义为 `required` 类型,则 Parquet 无法处理该值,从而抛出异常 [^1]。 ### 解决方案 #### 1. 数据清洗与默认值设置 在写入 Parquet 文件之前,应对数据进行清洗,确保所有字段值不为 `NULL`。可以通过设置默认值或使用可空类型来替代 `NULL` 值。 在 Pentaho Kettle 中,可以使用“JavaScript”步骤或“计算器”步骤对字段进行处理,将 `NULL` 替换为默认值或合理的占位符。例如: ```javascript // JavaScript 步骤中将 NULL 替换为默认值 var name = name == null ? "unknown" : name; ``` #### 2. 定义支持 `NULL` 值的 Parquet Schema Parquet 支持使用 `optional` 关键字定义可空字段。在配置 Parquet Output 插件时,应确保 schema 中允许 `NULL` 值的字段被正确标记为 `optional` 类型。 ```parquet message Example { optional binary name (UTF8); } ``` 在 Kettle 中配置 Parquet 输出时,手动编辑 schema 定义,将可能为 `NULL` 的字段设置为 `optional`,以避免运行时异常 [^1]。 #### 3. 使用可空类型处理非字符串字段 对于非字符串字段,如果允许 `NULL` 值,则应确保在 schema 中使用 `optional` 类型。例如,在整数字段中,若输入值为 `NULL`,但字段被定义为 `required`,则可能导致数据被错误解析为默认值(如 `0`) [^1]。 ```parquet message Example { optional int32 age; } ``` ### 预防措施 为避免类似问题再次发生,建议在数据处理流程中加入以下措施: - **字段类型验证**:在写入 Parquet 文件前,验证所有字段是否符合 schema 定义。 - **数据完整性检查**:使用“过滤记录”步骤或“字段选择”步骤,确保所有字段值有效。 - **Schema 版本管理**:定期检查并更新 Parquet schema,确保其与数据结构保持同步。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值