Hbase问题|反序列化SCAN字符串时google protobuf标记不匹配错误

时间:2015-05-28 13:35:02

标签: hadoop hbase protocol-buffers yarn

背景信息:我正在将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);
}

可能的原因:我怀疑我错过了一些依赖,或者底层罐子中存在一些依赖性不匹配。
感谢你解决这个问题的任何帮助吗?

1 个答案:

答案 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。