【问题标题】:Avro doesn't provide backward compatibilityAvro 不提供向后兼容性
【发布时间】:2018-04-09 03:47:55
【问题描述】:

我需要通过流来发送我的数据,所以我选择了 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");
}

【问题讨论】:

    标签: java avro backwards-compatibility


    【解决方案1】:

    您可能必须定义您正在寻找的向后兼容性范围。您是否期望添加新属性?或者您要删除任何属性吗?要处理这两种情况,可以使用不同的选项。

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

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

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

    如果您打算删除一个属性,您可以继续解析该属性,但不要在应用程序中使用它。请注意,这必须在一定时期内发生,并且必须给消费者足够的时间来更改他们的程序,然后才能完全停用该属性。确保记录一条语句以指示在不应该发送属性时发现了该属性(或者最好向客户端系统发送带有警告的通知)。

    除了以上几点,还有一篇非常棒的博客讲了backward/forward compatibility

    【讨论】:

    • 我已经指定了默认值。运行代码时出现 java.io.EOFException。
    • 即使我有默认设置,我也遇到了同样的问题。你终于让它工作了吗?
    【解决方案2】:

    向后兼容性意味着您可以使用较旧的架构对数据进行编码,而知道最新架构的读取器仍然可以解码数据。

    Explanation from Confluent's website

    因此,为了解码具有向后兼容性的 Avro 数据,您的读者需要访问最新的架构。例如,这可以使用架构注册表来完成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-18
      • 1970-01-01
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 2012-01-19
      相关资源
      最近更新 更多