Java parquet.io.ParquetDecodingException:无法读取文件中块-1中0处的值

Java parquet.io.ParquetDecodingException:无法读取文件中块-1中0处的值,java,hadoop,apache-spark,hive,Java,Hadoop,Apache Spark,Hive,我使用saveAsTable方法在配置单元中保存了一个远程DB表,现在,当我尝试使用CLI命令select*from table_name访问配置单元表数据时,出现以下错误: 2016-06-15 10:49:36,866 WARN [HiveServer2-Handler-Pool: Thread-96]: thrift.ThriftCLIService (ThriftCLIService.java:FetchResults(681)) - Error fetching results: o

我使用
saveAsTable
方法在配置单元中保存了一个远程DB表,现在,当我尝试使用CLI命令
select*from table_name
访问配置单元表数据时,出现以下错误:

2016-06-15 10:49:36,866 WARN  [HiveServer2-Handler-Pool: Thread-96]:
thrift.ThriftCLIService (ThriftCLIService.java:FetchResults(681)) -
Error fetching results: org.apache.hive.service.cli.HiveSQLException:
java.io.IOException: parquet.io.ParquetDecodingException: Can not read
value at 0 in block -1 in file hdfs:

你知道我可能做错了什么吗?

你能用Avro代替拼花地板来存放你的蜂巢桌吗?我遇到这个问题是因为我使用的是Hive的Decimal数据类型,而Spark的拼花地板不能很好地使用Decimal。如果发布表模式和一些数据示例,调试将更容易

另一个可能的选择是使用双精度而不是十进制,但这不是我的数据的选项,因此我无法报告它是否有效

我有一个类似的错误(但在非负块中有一个正索引),这是因为我创建了拼花地板数据,其中一些Spark数据框类型在实际为空时标记为不可空

在我的例子中,我因此将错误解释为Spark试图从某个不可为null的类型读取数据,并遇到意外的null值

更令人困惑的是,在读取拼花地板文件后,Spark使用
printSchema()
报告所有字段都可以为空,不管它们是否为空。然而,在我的例子中,使它们在原始拼花文件中真正为空解决了这个问题


现在,问题发生在“块-1中的0”这一事实是可疑的:实际上看起来几乎没有找到数据,因为块-1看起来Spark甚至没有开始读取任何内容(只是猜测)。

这里看起来像是架构不匹配的问题。 如果您将模式设置为不可为Null,并使用None值创建数据帧,Spark将抛出ValueError:此字段不可为Null,但未得到任何错误

[Pyspark]

from pyspark.sql.functions import * #udf, concat, col, lit, ltrim, rtrim
from pyspark.sql.types import *  

schema = ArrayType(StructType([StructField('A', IntegerType(), nullable=False)]))
# It will throw "ValueError". 
df = spark.createDataFrame([[[None]],[[2]]],schema=schema) 
df.show()
但如果您使用udf,则情况并非如此

使用相同的模式,如果使用udf进行转换,即使udf返回None,也不会抛出VALUERROR。它是数据模式不匹配发生的地方

例如:

df = spark.createDataFrame([[[1]],[[2]]], schema=schema)

def throw_none():
    def _throw_none(x):
        if x[0][0] == 1:
            return [['I AM ONE']] 
        else:
            return x 
    return udf(_throw_none, schema) 

# since value col only accept intergerType, it will throw null for 
# string "I AM ONE" in the first row. But spark did not throw ValueError
# error this time ! This is where data schema type mismatch happen !
df = df.select(throw_none()(col("value")).name('value'))  
df.show()  

然后,以下拼花写入和读取操作将抛出parquet.io.ParquetDecodingException错误

因此,如果您正在使用udf,请非常小心null值,在udf中返回正确的数据类型。除非没有必要,否则请不要在结构字段中设置null=False。设置为null=True将解决所有问题

问题: 查询impyla中的数据(spark job编写的数据)时遇到以下问题

根本原因:

这个问题是由于蜂巢和Spark中使用的拼花地板约定不同而引起的。在配置单元中,十进制数据类型表示为固定字节(int32)。在Spark 1.4或更高版本中,默认约定是对十进制数据类型使用标准拼花表示。根据基于列数据类型精度的标准拼花表示法,基础表示法会发生变化。
如: DECIMAL可用于注释以下类型:
int32:for 1捕获可能差异的另一种方法是观察两个来源(如hive和spark)产生的拼花地板文件的模式差异。您可以使用拼花工具转储模式(
brew安装拼花工具
for macos):


我也有一个类似的错误,在我的例子中,我缺少默认构造函数

你能打印该表的数据架构吗?我使用spark应用程序将数据写入配置单元,当我在色调中读取配置单元表时,发生了此错误。这对我来说很有效,谢谢!你好,伊娜!欢迎来到堆栈溢出!谢谢你的贡献!一定要说明你的“类似”错误是什么,并解释它解决问题的原因。在这种情况下,为什么缺少默认构造函数会导致OP描述的问题?
df.write.parquet("tmp")
spark.read.parquet("tmp").collect()
ERROR: Error while processing statement: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.tez.TezTask. Vertex failed, vertexName=Map 1, vertexId=vertex_1521667682013_4868_1_00, diagnostics=[Task failed, taskId=task_1521667682013_4868_1_00_000082, diagnostics=[TaskAttempt 0 failed, info=[Error: Failure while running task:java.lang.RuntimeException: java.lang.RuntimeException: java.io.IOException: org.apache.parquet.io.ParquetDecodingException: Can not read value at 0 in block -1 in file hdfs://shastina/sys/datalake_dev/venmo/data/managed_zone/integration/ACCOUNT_20180305/part-r-00082-bc0c080c-4080-4f6b-9b94-f5bafb5234db.snappy.parquet
    at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.initializeAndRunProcessor(TezProcessor.java:173)
    at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.run(TezProcessor.java:139)
    at org.apache.tez.runtime.LogicalIOProcessorRuntimeTask.run(LogicalIOProcessorRuntimeTask.java:347)
    at org.apache.tez.runtime.task.TezTaskRunner$TaskRunnerCallable$1.run(TezTaskRunner.java:194)
    at org.apache.tez.runtime.task.TezTaskRunner$TaskRunnerCallable$1.run(TezTaskRunner.java:185)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:422)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1724)
    at org.apache.tez.runtime.task.TezTaskRunner$TaskRunnerCallable.callInternal(TezTaskRunner.java:185)
    at org.apache.tez.runtime.task.TezTaskRunner$TaskRunnerCallable.callInternal(TezTaskRunner.java:181)
    at org.apache.tez.common.CallableWithNdc.call(CallableWithNdc.java:36)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
--conf "spark.sql.parquet.writeLegacyFormat=true"
λ $ parquet-tools schema /usr/local/Cellar/apache-drill/1.16.0/libexec/sample-data/nation.parquet
message root {
  required int64 N_NATIONKEY;
  required binary N_NAME (UTF8);
  required int64 N_REGIONKEY;
  required binary N_COMMENT (UTF8);
}