我已经使用 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/