Невозможно десериализовать данные Protobuf (2.6.1), используя слоновую птицу и Hive в AWS
Я не могу десериализовать данные protobuf, в которых есть повторяющаяся строка, используя elephant-bird 4.14 с Hive. Похоже, это связано с тем, что функция многократных строк доступна только в Protobuf 2.6, а не в Protobuf 2.5. При выполнении моих запросов к кустам в кластере AWS EMR он использует Protobuf 2.5, который входит в комплект AWS Hive. Даже после явного добавления Protobuf 2.6 jar я не могу избавиться от этой ошибки. Я хочу знать, как я могу сделать улей, чтобы использовать Protobuf 2.6 jar, который я добавляю явно.
Ниже приведены запросы улья:
add jar s3://gam.test/hive-jars/protobuf-java-2.6.1.jar;
add jar s3://gam.test/hive-jars/GAMDataModel-1.0.jar;
add jar s3://gam.test/hive-jars/GAMCoreModel-1.0.jar;
add jar s3://gam.test/hive-jars/GAMAccessLayer-1.1.jar;
add jar s3://gam.test/hive-jars/RodbHiveStorageHandler-0.12.0-jarjar-final.jar;
add jar s3://gam.test/hive-jars/elephant-bird-core-4.14.jar;
add jar s3://gam.test/hive-jars/elephant-bird-hive-4.14.jar;
add jar s3://gam.test/hive-jars/elephant-bird-hadoop-compat-4.14.jar;
add jar s3://gam.test/hive-jars/protobuf-java-2.6.1.jar;
add jar s3://gam.test/hive-jars/GamProtoBufHiveDeserializer-1.0-jarjar.jar;
drop table GamRelationRodb;
CREATE EXTERNAL TABLE GamRelationRodb
row format serde "com.amazon.hive.serde.GamProtobufDeserializer"
with serdeproperties("serialization.class"=
"com.amazon.gam.rodb.model.RepeatedRelationshipWrapperProto$RepeatedRelationshipWrapper")
STORED BY 'com.amazon.rodb.hadoop.hive.RodbHiveStorageHandler' TBLPROPERTIES
("file.name" = 'GAM_Relationship',"file.path" ='s3://pathtofile/');
select * from GamRelationRodb limit 10;
Ниже приведен формат файла Protobuf:
message RepeatedRelationshipWrapper {
repeated relationship.Relationship relationships = 1;
}
message Relationship {
required RelationshipType type = 1;
repeated string ids = 2;
}
enum RelationshipType {
UKNOWN_RELATIONSHIP_TYPE = 0;
PARENT = 1;
CHILD = 2;
}
Ниже приведено исключение во время выполнения запроса:
Exception in thread "main" java.lang.NoSuchMethodError: com.google.protobuf.LazyStringList.getUnmodifiableView()Lcom/google/protobuf/LazyStringList;
at com.amazon.gam.model.RelationshipProto$Relationship.<init>(RelationshipProto.java:215)
at com.amazon.gam.model.RelationshipProto$Relationship.<init>(RelationshipProto.java:137)
at com.amazon.gam.model.RelationshipProto$Relationship$1.parsePartialFrom(RelationshipProto.java:239)
at com.amazon.gam.model.RelationshipProto$Relationship$1.parsePartialFrom(RelationshipProto.java:234)
at com.google.protobuf.CodedInputStream.readMessage(CodedInputStream.java:309)
at com.amazon.gam.rodb.model.RepeatedRelationshipWrapperProto$RepeatedRelationshipWrapper.<init>(RepeatedRelationshipWrapperProto.java:126)
at com.amazon.gam.rodb.model.RepeatedRelationshipWrapperProto$RepeatedRelationshipWrapper.<init>(RepeatedRelationshipWrapperProto.java:72)
at com.amazon.gam.rodb.model.RepeatedRelationshipWrapperProto$RepeatedRelationshipWrapper$1.parsePartialFrom(RepeatedRelationshipWrapperProto.java:162)
at com.amazon.gam.rodb.model.RepeatedRelationshipWrapperProto$RepeatedRelationshipWrapper$1.parsePartialFrom(RepeatedRelationshipWrapperProto.java:157)
at com.amazon.gam.rodb.model.RepeatedRelationshipWrapperProto$RepeatedRelationshipWrapper$Builder.mergeFrom(RepeatedRelationshipWrapperProto.java:495)
at com.amazon.gam.rodb.model.RepeatedRelationshipWrapperProto$RepeatedRelationshipWrapper$Builder.mergeFrom(RepeatedRelationshipWrapperProto.java:355)
at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:337)
at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:267)
at com.google.protobuf.AbstractMessageLite$Builder.mergeFrom(AbstractMessageLite.java:170)
at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:882)
at com.google.protobuf.AbstractMessage$Builder.mergeFrom(AbstractMessage.java:267)
at com.twitter.elephantbird.mapreduce.io.ProtobufConverter.fromBytes(ProtobufConverter.java:66)
at com.twitter.elephantbird.hive.serde.ProtobufDeserializer.deserialize(ProtobufDeserializer.java:59)
at com.amazon.hive.serde.GamProtobufDeserializer.deserialize(GamProtobufDeserializer.java:63)
at org.apache.hadoop.hive.ql.exec.FetchOperator.getNextRow(FetchOperator.java:502)
at org.apache.hadoop.hive.ql.exec.FetchOperator.pushRow(FetchOperator.java:428)
at org.apache.hadoop.hive.ql.exec.FetchTask.fetch(FetchTask.java:146)
at org.apache.hadoop.hive.ql.Driver.getResults(Driver.java:2098)
at org.apache.hadoop.hive.cli.CliDriver.processLocalCmd(CliDriver.java:252)
at org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:183)
at org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:399)
at org.apache.hadoop.hive.cli.CliDriver.executeDriver(CliDriver.java:776)
at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:714)
at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:641)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
at org.apache.hadoop.util.RunJar.main(RunJar.java:136)
1 ответ
Protobuf - хрупкая библиотека. Он может быть совместим с проводным форматом между версиями 2.x, но сгенерированные protoc классы будут ссылаться только на JAR protobuf той же версии, что и компилятор protoc.
По сути, это означает, что вы не можете обновить protobuf, кроме как путем хореографии всех зависимостей. Великолепное обновление Protobuf в 2013 году произошло, когда Hadoop, Hbase, Hive &c обновились, и после этого: все заморозились до версии 2.5, вероятно, на всю жизнь кодовой линии Hadoop 2.x, если только все не затенено или Java 9 не скрывается. эта проблема.
Мы больше боимся обновлений protobuf, чем обновлений до Гуавы и Джексона, так как последний нарушает только каждую библиотеку, а не формат проводного соединения.
Смотрите HADOOP-13363 на тему обновления 2.x и HDFS-11010 на вопрос о переходе на protobuf 3 в магистрали hadoop. Это грязно, так как это меняет формат проводов, разрывы протокола protobuf-json и другие вещи.
Лучше всего просто сделать вывод, что "двоичной совместимости кода protobuf не найдено", и придерживаться protobuf 2.5. Сожалею.
Вы можете взять весь стек библиотек, который хотите использовать, перестроить их с помощью обновленного компилятора protoc, соответствующего protobuf.jor, с любыми другими необходимыми исправлениями. Я бы порекомендовал это только смелым, но мне любопытно, что получится. Если вы попробуете это, дайте нам знать, как это получилось
Дальнейшее чтение страха перед зависимостями