当前位置: 首页 > 知识库问答 >
问题:

架构演进上的 Avro 反序列化错误

沃弘图
2023-03-14

我有2个模式:

模式1(旧模式):

{
    "namespace": "com.org.package",
    "type": "record",
    "name": "EventModel",
    "fields": [
                    {
                        "name":"name",
                        "type":"string"
                    },
                    {
                        "name":"id",
                        "type":"long"
                    }
]
}

我用一个布尔字段更新了模式:

方案2(新方案):

{
    "namespace": "com.org.package",
    "type": "record",
    "name": "EventModel",
    "fields": [
                    {
                        "name":"name",
                        "type":"string"
                    },
                    {
                        "name":"id",
                        "type":"long"
                    },
                    {
                        "name":"isActive",
                        "type":"boolean",
                        "default":false
                    }
]
}

kafka主题包含属于旧模式(schema1)的消息。更新使用者模式后,即使更新字段中存在默认值,使用者也无法反序列化旧模式消息。

根据Avro文档:

if the reader's record schema has a field that contains a default value, and writer's schema does not have a field with the same name, then the reader should use the default value from its field.
if the reader's record schema has a field with no default value, and writer's schema does not have a field with the same name, an error is signalled.

阿夫罗博士

我得到以下错误,而反序列化:

java.io.EOFException: null
    at org.apache.avro.io.BinaryDecoder.readBoolean(BinaryDecoder.java:140) ~[avro-1.9.1.jar!/:1.9.1]
    at org.apache.avro.io.ValidatingDecoder.readBoolean(ValidatingDecoder.java:77) ~[avro-1.9.1.jar!/:1.9.1]
    at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:194) ~[avro-1.9.1.jar!/:1.9.1]
    at org.apache.avro.specific.SpecificDatumReader.readField(SpecificDatumReader.java:136) ~[avro-1.9.1.jar!/:1.9.1]
    at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:237) ~[avro-1.9.1.jar!/:1.9.1]
    at org.apache.avro.specific.SpecificDatumReader.readRecord(SpecificDatumReader.java:123) ~[avro-1.9.1.jar!/:1.9.1]
    at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:170) ~[avro-1.9.1.jar!/:1.9.1]
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:151) ~[avro-1.9.1.jar!/:1.9.1]
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:144) ~[avro-1.9.1.jar!/:1.9.1]

当记录缺少字段时,为什么默认值未应用于使用者?任何帮助都非常感谢。提前致谢!

共有1个答案

司空坚
2023-03-14

尝试将isActive的类型更改为booleannull,而不仅仅是boolean。类似:

{
    "name": "isActive",
    "type": ["boolean", "null"],
    "default": false
}

它将使模式向后兼容。

 类似资料:
  • 在阅读avro文档时,例如[1],我了解到,支持模式演化,如果我添加了具有指定默认值的列,它应该是向后兼容的(当我再次删除它时,甚至是向前兼容的)。听起来不错,所以我添加了一个列,定义为: 并尝试从一开始就使用具有此架构的某个主题,它失败并显示消息: 提供更多的信息。Avro模式定义了一个顶级类型,具有2个字段。描述消息类型的字符串,以及N种类型的并集。可以读取所有N-1个未修改的类型,但是不能读

  • 我在两个独立的AVCS模式文件中定义了记录的两个版本。我使用命名空间来区分版本SimpleV1.avsc 示例JSON 版本2只是有一个带有默认值的附加描述字段。 SimpleV2.avsc 示例JSON 这两个模式都序列化为Java类。在我的示例中,我将测试向后兼容性。V1写入的记录应由使用V2的读取器读取。我希望看到插入默认值。只要我不使用枚举,这就可以工作。 检查读者作家兼容性方法确认模式是

  • 我是Avro和Kafka的新手,我花了几天时间来发送关于Kafka主题的序列化数据...不成功。 让我来解释一下我想要达到的目标: 在生产者方面,我通过SOAP接收数据并发送关于Kafka主题的内容。我正在使用CXF从WSDL生成POJO,并且编写了相应的模式。我正在尝试做的是序列化由CXF解封的对象,并在我的Kafka主题上发送它们。 在web上找到的大多数示例中,Avro记录都是使用已知的模式

  • 我正在创建一个avro类,它包含一个字符串和一个映射作为字段。我可以通过maven生成avro类,并且能够在localhost:8081中创建注册表

  • 目前,我正在使用Avro1.8.0序列化/反序列化对象,但面临一些问题,特别是java.util.Map对象。不面临其他类型对象的问题。 这里的示例代码- 在deserialize方法中,我试图根据输入数据获取模式,但avro抛出错误- 多谢了。