背景信息:我正在将HBase上的MR作业从CDH 2.0.0-cdh4.5.0(Hadoop1)迁移到HDP 2.2.0.0-2041(YARN)。经过微小的更改后,代码是针对HDP 2.2.0.0-2041编译的。
问题:我正在尝试运行oozie工作流,在HBase上创建扫描后执行一系列MR作业。以编程方式创建扫描,然后进行序列化 - 反序列化,然后将其交给映射器以从HBase获取批处理。
问题:当TableInputFormat在内部尝试反序列化扫描字符串时,它会抛出一个错误,指示引擎盖下的google protobuf无法反序列化该字符串。堆栈跟踪如下所示。
线程中的异常" main" java.io.IOException:com.google.protobuf.InvalidProtocolBufferException:协议消息end-group标记与期望标记不匹配。 at com.flipkart.yarn.test.TestScanSerialiseDeserialise.convertStringToScan(TestScanSerialiseDeserialise.java:37)at com.flipkart.yarn.test.TestScanSerialiseDeserialise.main(TestScanSerialiseDeserialise.java:25)引起:......
可重现:我可以在我粘贴的示例代码中重现这一点
示例代码:
Scan scan1 = constructScanObjectForUsers("A");
String json = scan1.toJSON();
Scan scan2 = convertStringToScan(Base64.encodeBytes(json.getBytes()));
.......
private static Scan convertStringToScan(String base64) throws IOException {
byte[] decoded = Base64.decode(base64);
// System.out.println(new String(decoded));
ClientProtos.Scan scan;
try {
scan = ClientProtos.Scan.parseFrom(decoded);
} catch (InvalidProtocolBufferException ipbe) {
throw new IOException(ipbe);
}
return ProtobufUtil.toScan(scan);
}
可能的原因:我怀疑我错过了一些依赖,或者底层罐子中存在一些依赖性不匹配。
感谢你解决这个问题的任何帮助吗?
答案 0 :(得分:0)
Scan scan1 = constructScanObjectForUsers("A");
String json = scan1.toJSON();
Scan scan2 = convertStringToScan(Base64.encodeBytes(json.getBytes()));
在这里,您似乎将消息编码为JSON。然后,您将base64应用于JSON文本。通常base64仅适用于二进制,但JSON是文本。
byte[] decoded = Base64.decode(base64);
// System.out.println(new String(decoded));
ClientProtos.Scan scan;
try {
scan = ClientProtos.Scan.parseFrom(decoded);
在这里,您可以取消某些文本,然后将其解码为protobuf。这是来自上面的相同数据吗?因为如果是这样,这不会起作用:JSON和Protobuf是不同的格式。如果你想解码为Protobuf,你需要编码为Protobuf,而不是JSON。