我需要通过流发送数据,因此我选择了Avro进行数据序列化和反序列化。但是现有的使用avro阅读器的实现不支持向后兼容。将序列化的数据写入文件并从文件读取支持向后兼容性。我如何在不了解作者架构的情况下实现向后兼容性。我发现许多与此有关的stackoverflow问题。但是我没有找到解决此问题的任何方法。有人可以帮我解决这个问题吗?

以下是我的序列化器和反序列化器方法。

   public static byte[] serialize(String json, Schema schema) throws IOException {
        GenericDatumWriter<Object> writer = new GenericDatumWriter<>(schema);
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        Encoder encoder = EncoderFactory.get().binaryEncoder(output, null);
        DatumReader<Object> reader = new GenericDatumReader<>(schema);
        Decoder decoder = DecoderFactory.get().jsonDecoder(schema, json);
        Object datum = reader.read(null, decoder);
        writer.write(datum, encoder);
        encoder.flush();
        output.flush();
        return output.toByteArray();

}

    public static String deserialize(byte[] avro, Schema schema) throws IOException {
        GenericDatumReader<Object> reader = new GenericDatumReader(schema);
        Decoder decoder = DecoderFactory.get().binaryDecoder(avro, null);
        Object datum = reader.read(null, decoder);
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        JsonEncoder encoder = EncoderFactory.get().jsonEncoder(schema, output);

        DatumWriter<Object> writer = new GenericDatumWriter(schema);
        writer.write(datum, encoder);
        encoder.flush();
        output.flush();
        return new String(output.toByteArray(), "UTF-8");
}

最佳答案

您可能必须定义要向后兼容的范围。您是否希望添加新属性?或者您要删除任何属性?为了处理这两种情况,有不同的选项可用。

confluent blog所述,可以添加新属性,并且可以使avro序列化/反序列化活动向后兼容,您必须为新属性指定default值。像下面这样

{"name": "size", "type": "string", "default": "XL"}


另一个选项是指定reader and writer schemas exclusively。但是,正如您的问题所述,这似乎并不是您要寻找的选择。

如果您打算删除属性,则可以继续解析该属性,但不要在应用程序中使用它。请注意,这必须持续一定的时间,并且必须在完全淘汰属性之前,给消费者足够的时间来更改其程序。确保记录一条语句以指示在不应该发送属性时找到了该属性(或者最好将警告发送给客户端系统通知)。

除了上述几点之外,还有一个很棒的博客谈论backward/forward compatibility

关于java - Avro不提供向后兼容性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49725238/

10-10 13:15