我在Hadoop 3.3.4和Tez 0.9.2上使用Hive 3.1.3版本。当我创建一个包含分割的ORC表并尝试查询它时,我得到一个ORC split generation failed
异常。如果我连接表,这在某些情况下解决了这个问题。然而,在另一些国家,这个问题仍然存在。
首先我像这样创建表,然后尝试查询它:
CREATE TABLE ClaimsOrc STORED AS ORC
AS
SELECT *
FROM ClaimsImport;
SELECT COUNT(*) FROM ClaimsOrc WHERE ClaimID LIKE '%8%';
然后得到以下异常:
Vertex failed, vertexName=Map 1, vertexId=vertex_1667735849290_0008_6_00, diagnostics=[Vertex vertex_1667735849290_0008_6_00 [Map 1] killed/failed due to:ROOT_INPUT_INIT_FAILURE, Vertex Input: claimsorc initializer failed, vertex=vertex_1667735849290_0008_6_00 [Map 1], java.lang.RuntimeException: ORC split generation failed with exception: java.lang.NoSuchMethodError: org.apache.hadoop.fs.FileStatus.compareTo(Lorg/apache/hadoop/fs/FileStatus;)I
at org.apache.hadoop.hive.ql.io.orc.OrcInputFormat.generateSplitsInfo(OrcInputFormat.java:1851)
at org.apache.hadoop.hive.ql.io.orc.OrcInputFormat.getSplits(OrcInputFormat.java:1939)
at org.apache.hadoop.hive.ql.io.HiveInputFormat.addSplitsForGroup(HiveInputFormat.java:519)
at org.apache.hadoop.hive.ql.io.HiveInputFormat.getSplits(HiveInputFormat.java:765)
at org.apache.hadoop.hive.ql.exec.tez.HiveSplitGenerator.initialize(HiveSplitGenerator.java:243)
at org.apache.tez.dag.app.dag.RootInputInitializerManager$InputInitializerCallable$1.run(RootInputInitializerManager.java:278)
at org.apache.tez.dag.app.dag.RootInputInitializerManager$InputInitializerCallable$1.run(RootInputInitializerManager.java:269)
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:1657)
at org.apache.tez.dag.app.dag.RootInputInitializerManager$InputInitializerCallable.call(RootInputInitializerManager.java:269)
at org.apache.tez.dag.app.dag.RootInputInitializerManager$InputInitializerCallable.call(RootInputInitializerManager.java:253)
at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:108)
at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:41)
at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:77)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
Caused by: java.util.concurrent.ExecutionException: java.lang.NoSuchMethodError: org.apache.hadoop.fs.FileStatus.compareTo(Lorg/apache/hadoop/fs/FileStatus;)I
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at org.apache.hadoop.hive.ql.io.orc.OrcInputFormat.generateSplitsInfo(OrcInputFormat.java:1790)
但是,如果我先连接表,它将输出文件合并到更少的小文件中,表可以正常工作:
ALTER TABLE ClaimsOrc CONCATENATE;
OK
Time taken: 11.673 seconds
SELECT COUNT(*) FROM ClaimsOrc WHERE ClaimID LIKE '%8%';
OK
1463419
Time taken: 7.446 seconds, Fetched: 1 row(s)
它似乎是出了问题,如何初始的CTAS查询计算分割,CONCATENATE
修复它在某些情况下。但在某些情况下,它不会,而且没有解决办法。我该如何解决这个问题?
其他一些值得注意的事情:
- 使用
DESCRIBE EXTENDED ClaimsOrc;
表示ClaimsOrc
是一个ORC表。 - 源表
ClaimsImport
包含大约24个以管道分隔的压缩文件。 - 在
CONCATENATE
之前,ClaimsOrc
表大约包含24个文件 - 在
CONCATENATE
之后,ClaimsOrc
表只包含3个文件分割 - 在
CONCATENATE
命令之前,ORC文件看起来是有效的。使用orcfiledump命令,我没有在我抽查的几个文件中看到任何错误。
Tez 0.9.2包含需要放置到HDFS位置的tez.tar.gz
。这个tez.tar.gz默认包含hadoop-common-2.7.2.jar(它没有compareTo方法,该方法会像错误中显示的那样抛出异常)
用最新的Hadoop jar包重新打包这个jar包,或者从你的版本(Hadoop 3.3.4)复制,你可能需要用其他的jar包重新打包,比如guava, Woodstox, stax2 api等等。将这个重新打包的tez的tar - gz放到所有节点和hdfs的位置。
这个错误应该消失。你可能会遇到其他错误,就像我说的,你可以通过添加额外的Hadoop依赖jar来解决。
否则将tez升级到0.10。x版本,验证其Hadoop版本。希望它是hadoop3。这将直接成为解决方案。