微信搜索lxw1234bigdata | 邀请体验:数阅–数据管理、OLAP分析与可视化平台 | 赞助作者:赞助作者

Hive中使用ORC遇到的protobuf版本问题

Hive lxw1234@qq.com 18039℃ 0评论

Hive从0.11版本开始提供了ORC的文件格式,ORC文件不仅仅是一种列式文件存储格式,最重要的是有着很高的压缩比,并且对于MapReduce 来说是可切分(Split)的。因此,在Hive中使用ORC作为表的文件存储格式,不仅可以很大程度的节省HDFS存储资源,而且对数据的查询和处理性 能有着非常大的提升,因为ORC较其他文件格式压缩比高,查询任务的输入数据量减少,使用的Task也就减少了。

之前有文章介绍过ORC的使用和优化。

更高的压缩比,更好的性能–使用ORC文件格式优化Hive
Hive性能优化之ORC索引–Row Group Index vs Bloom Filter Index

在使用ORC过程中,需要关注Hive中的protobuf版本是否和你使用的Hadoop中protobuf的版本一致,如果不一致,将不能正常使用ORC,比如,我们一个老的Hadoop集群使用的Hadoop版本为hadoop-0.20.2-cdh3u2(protobuf版本为protobuf-java-2.4.0a),Hive的版本为apache-hive-0.13.1-bin(protobuf版本为protobuf-java-2.5.0.jar),这样,在Hive中生成存储格式为ORC的表数据时候便会报错:

FATAL org.apache.hadoop.hive.ql.exec.mr.ExecMapper: java.lang.VerifyError: class org.apache.hadoop.hive.ql.io.orc.OrcProto$RowIndex overrides final method getUnknownFields.()Lcom/google/protobuf/UnknownFieldSet;
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
	at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
	at org.apache.hadoop.hive.ql.io.orc.WriterImpl.(WriterImpl.java:129)
	at org.apache.hadoop.hive.ql.io.orc.OrcFile.createWriter(OrcFile.java:369)
	at org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat$OrcRecordWriter.write(OrcOutputFormat.java:83)
	at org.apache.hadoop.hive.ql.exec.FileSinkOperator.processOp(FileSinkOperator.java:621)
	at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:793)
	at org.apache.hadoop.hive.ql.exec.SelectOperator.processOp(SelectOperator.java:87)
	at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:793)
	at org.apache.hadoop.hive.ql.exec.TableScanOperator.processOp(TableScanOperator.java:92)
	at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:793)
	at org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:540)
	at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:177)
	at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:50)
	at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:391)
	at org.apache.hadoop.mapred.MapTask.run(MapTask.java:325)
	at org.apache.hadoop.mapred.Child$4.run(Child.java:270)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:396)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1127)
	at org.apache.hadoop.mapred.Child.main(Child.java:264)

很明显,这正是由于Protobuf版本不一致导致的问题。

那么想要解决该问题,如果不是刚开始做版本规划,那么无论是降低Hive版本,还是升级Hadoop版本,都不太容易,上面跑的业务太多了,很容易出现问题。

另一种可行的方法是使用protobuf2.4.0a重新编译Hive0.13.1,这种做法风险最低。

本文介绍如何使用protobuf2.4.0编译Hive0.13.1,使其在较低版本的Hadoop上,可以正常使用ORC文件格式。

下载Hive0.13.1源码:

http://archive.apache.org/dist/hive/

源码解压之后,进入源码根目录,

修改pom.xml

找到<protobuf.version>2.5.0</protobuf.version>,修改为:<protobuf.version>2.4.0a</protobuf.version>

执行编译命令:

mvn clean package -DskipTests -Phadoop-1 -Pdist

其中,参数-Phadoop-1指定了使用MR1的Hadoop。

遇到的第一个错误是在编译hive-exec时候:

[ERROR] symbol:   class Parser
[ERROR] location: package com.google.protobuf
[ERROR] /root/apache-hive-0.13.1-src/ql/src/gen/protobuf/gen-java/org/apache/hadoop/hive/ql/io/orc/OrcProto.java:[12939,31] cannot find symbol
[ERROR] symbol:   class Parser
[ERROR] location: package com.google.protobuf
......
[ERROR] location: package com.google.protobuf
[ERROR] /root/apache-hive-0.13.1-src/ql/src/gen/protobuf/gen-java/org/apache/hadoop/hive/ql/io/orc/OrcProto.java:[169,9] getUnknownFields() in org.apache.hadoop.hive.ql.io.orc.OrcProto.IntegerStatistics cannot override getUnknownFields() in com.google.protobuf.GeneratedMessage
[ERROR] overridden method is final
[ERROR] /root/apache-hive-0.13.1-src/ql/src/gen/protobuf/gen-java/org/apache/hadoop/hive/ql/io/orc/OrcProto.java:[189,20] cannot find symbol
[ERROR] symbol:   method parseUnknownField(com.google.protobuf.CodedInputStream,com.google.protobuf.UnknownFieldSet.Builder,com.google.protobuf.ExtensionRegistryLite,int)
[ERROR] location: class org.apache.hadoop.hive.ql.io.orc.OrcProto.IntegerStatistics
[ERROR] /root/apache-hive-0.13.1-src/ql/src/gen/protobuf/gen-java/org/apache/hadoop/hive/ql/io/orc/OrcProto.java:[213,16] cannot find symbol
[ERROR] symbol:   method setUnfinishedMessage(org.apache.hadoop.hive.ql.io.orc.OrcProto.IntegerStatistics)
[ERROR] location: variable e of type com.google.protobuf.InvalidProtocolBufferException
[ERROR] /root/apache-hive-0.13.1-src/ql/src/gen/protobuf/gen-java/org/apache/hadoop/hive/ql/io/orc/OrcProto.java:[216,28] cannot find symbol
[ERROR] symbol:   method setUnfinishedMessage(org.apache.hadoop.hive.ql.io.orc.OrcProto.IntegerStatistics)
[ERROR] location: class com.google.protobuf.InvalidProtocolBufferException
[ERROR] /root/apache-hive-0.13.1-src/ql/src/gen/protobuf/gen-java/org/apache/hadoop/hive/ql/io/orc/OrcProto.java:[219,9] cannot find symbol
[ERROR] symbol:   method makeExtensionsImmutable()
[ERROR] location: class org.apache.hadoop.hive.ql.io.orc.OrcProto.IntegerStatistics
[ERROR] /root/apache-hive-0.13.1-src/ql/src/gen/protobuf/gen-java/org/apache/hadoop/hive/ql/io/orc/OrcProto.java:[230,11] cannot find symbol
......

遇到的第二个错,是编译hive-hbase-hanlder时候:

[ERROR] symbol:   class Parser
[ERROR] location: package com.google.protobuf
[ERROR] /root/apache-hive-0.13.1-src/hcatalog/storage-handlers/hbase/src/gen-java/org/apache/hcatalog/hbase/snapshot/RevisionManagerEndpointProtos.java:[10366,40] cannot find symbol
[ERROR] symbol:   class Parser
[ERROR] location: package com.google.protobuf
[ERROR] /root/apache-hive-0.13.1-src/hcatalog/storage-handlers/hbase/src/gen-java/org/apache/hcatalog/hbase/snapshot/RevisionManagerEndpointProtos.java:[10377,33] cannot find symbol
[ERROR] symbol:   class Parser
[ERROR] location: package com.google.protobuf
[ERROR] /root/apache-hive-0.13.1-src/hcatalog/storage-handlers/hbase/src/gen-java/org/apache/hcatalog/hbase/snapshot/RevisionManagerEndpointProtos.java:[74,9] getUnknownFields() in org.apache.hcatalog.hbase.snapshot.RevisionManagerEndpointProtos.CreateTableRequest cannot override getUnknownFields() in com.google.protobuf.GeneratedMessage
[ERROR] overridden method is final
[ERROR] /root/apache-hive-0.13.1-src/hcatalog/storage-handlers/hbase/src/gen-java/org/apache/hcatalog/hbase/snapshot/RevisionManagerEndpointProtos.java:[94,20] cannot find symbol
[ERROR] symbol:   method parseUnknownField(com.google.protobuf.CodedInputStream,com.google.protobuf.UnknownFieldSet.Builder,com.google.protobuf.ExtensionRegistryLite,int)
......

这两个错误原因相同,涉及到两个类文件:

ql/src/gen/protobuf/gen-java/org/apache/hadoop/hive/ql/io/orc/OrcProto.java

hcatalog/storage-handlers/hbase/src/gen-java/org/apache/hcatalog/hbase/snapshot/RevisionManagerEndpointProtos.java

原因是这两个文件使用protobuf2.5.0生成的,因此不能使用protobuf2.4.0编译。

解决办法是使用protobuf2.4.0,重新生成这两个类文件。

首先需要安装protobuf2.4.0a,下载源码,并解压,进入解压后的根目录,执行下面的命令编译并安装(安装需要root权限):

tar -xzvf protobuf_2.4.0a.orig.tar.gz
cd protobuf-2.4.0a/
./configure
make
make check
make install
##安装完后,查看protoc版本:
[root@dev protobuf-2.4.0a]# protoc --version
libprotoc 2.4.0

进入Hive-0.13.1源码根目录:

cd /root/apache-hive-0.13.1-src

使用protoc命令重新生成这两个类文件:

protoc ql/src/protobuf/org/apache/hadoop/hive/ql/io/orc/orc_proto.proto --java_out=ql/src/gen/protobuf/gen-java/
protoc ./hcatalog/storage-handlers/hbase/src/protobuf/org/apache/hcatalog/hbase/snapshot/RevisionManagerEndpoint.proto --java_out=hcatalog/storage-handlers/hbase/src/gen-java/

再次执行编译命令:

mvn clean package -DskipTests -Phadoop-1 -Pdist

编译成功,编译之后的hive-exec-0.13.1.jar 位于ql/target目录下,将该jar包拷贝到$HIVE_HOME/lib目录下,覆盖原来的。

重新启动Hive客户端,即可正常生成和查询ORC文件格式的表。

如果需要使用hive-hbase-hanlder,则把hbase-handler/target/hive-hbase-handler-0.13.1.jar复制到$HIVE_HOME/lib下即可。

相关下载:

protobuf_2.4.0a源码:

链接: http://pan.baidu.com/s/1pL2AgIZ 密码: a2hz

基于protobuf-2.4.0a编译好的hive-exec-0.13.1.jar和hive-hbase-handler-0.13.1.jar,如果需要,可以直接下载使用:

链接: http://pan.baidu.com/s/1bpdWgwf 密码: cb43

 

 

如果觉得本博客对您有帮助,请 赞助作者

转载请注明:lxw的大数据田地 » Hive中使用ORC遇到的protobuf版本问题

喜欢 (3)
分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址