java - Parquet .io.ParquetDecodingException : Can not read value at 0 in block -1 in file

标签 java hadoop apache-spark hive

我已经使用 saveAsTable 方法在 Hive 中保存了一个远程数据库表,现在当我尝试使用 CLI 命令 select * from table_name 访问 Hive 表数据时,它给出了我的错误如下:

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:

知道我在这里做错了什么吗?

最佳答案

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

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)

根本原因:

此问题是由于 Hive 和 Spark 中使用不同的 parquet 约定引起的。在 Hive 中,十进制数据类型表示为固定字节 (INT 32)。在 Spark 1.4 或更高版本中,默认约定是对十进制数据类型使用标准 Parquet 表示。根据基于列数据类型精度的标准 Parquet 表示,底层表示发生了变化。
例如: DECIMAL 可用于注释以下类型: int32:对于 1 <= 精度 <= 9 int64:对于 1 <= 精度 <= 18;精度 < 10 将产生警告

因此,此问题仅发生在使用在不同 Parquet 约定中具有不同表示的数据类型时。如果数据类型是 DECIMAL (10,3),两种约定都将其表示为 INT32,因此我们不会遇到问题。如果您不知道数据类型的内部表示,则可以安全地使用与读取时写入相同的约定。使用 Hive,您无法灵活地选择 Parquet 约定。但有了 Spark,您就可以做到。

解决方案: Spark 用于写入 Parquet 数据的约定是可配置的。这是由属性 spark.sql.parquet.writeLegacyFormat 决定的 默认值为假。如果设置为“true”,Spark 将使用与 Hive 相同的约定来写入 Parquet 数据。这将有助于解决问题。

--conf "spark.sql.parquet.writeLegacyFormat=true"

引用资料:

关于java - Parquet .io.ParquetDecodingException : Can not read value at 0 in block -1 in file,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37829334/

相关文章:

Hadoop 守护进程不停止

java - Spring Data JPA 之间 findBy/findAllBy 的区别

java - 框架内部日志转到 system.out (websphere 7.0)

java - 为什么我的 double 数学结果是错误的?

hadoop - 失败 : Execution Error, 在配置单元中的连接操作期间从 org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask​​ 返回代码 2

apache-spark - 无法在 Spark 中更改 hive.exec.max.dynamic.partitions

java - ServerSocket(端口)上的困惑

java - 如何读取和写入多个子文件夹?

apache-spark - NPE 与 Joda DateTime 一起 Spark

apache-spark - 将数据存储到 PySpark(Azure - DataBricks)中的数据库非常慢