上下文:我正在将我在HBase上的MR作业从cdh2.0.0-cdh4.5.0 (Hadoop1)迁移到HDP 2.2.0.0-2041 (YARN)。在做了一些小改动之后,针对HDP 2.2.0.0-2041编译了代码。
问题:我正在尝试运行一个oozie工作流,在HBase上创建扫描后执行一系列MR作业。扫描是以编程方式创建的,然后序列化-反序列化,然后将其交给映射器从HBase获取批处理。
问题:当TableInputFormat内部尝试反序列化扫描字符串时,它抛出一个错误,表明在幕后谷歌协议无法反序列化字符串。堆栈跟踪如下所示。
线程"main“组中出现异常: com.google.protobuf.InvalidProtocolBufferException: java.io.IOException消息结束组标记与预期标记不匹配。在com.flipkart.yarn.test.TestScanSerialiseDeserialise.main(TestScanSerialiseDeserialise.java:25)的com.flipkart.yarn.test.TestScanSerialiseDeserialise.convertStringToScan(TestScanSerialiseDeserialise.java:37),原因是:......
可重现:我能够在我粘贴的示例代码中重现这一点
示例代码:
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);
}
可能的原因:我怀疑我错过了提供一些依赖项,或者在底层jars中有一些依赖项不匹配。
在解决这个问题上有什么帮助吗?
发布于 2015-05-29 18:22:03
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);
在这里,您可以取消一些文本的Base64,然后将其解码为一个协议缓冲区。这是来自上面的相同数据吗?因为如果是这样的话,这将不起作用: JSON和Protobuf是不同的格式。如果你想解码为Protobuf,你需要编码为Protobuf,而不是JSON。
https://stackoverflow.com/questions/30508130
复制