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

Avro模式演化

伏子辰
2023-03-14

我有两个问题:

>

我曾尝试使用模式V1编写记录,并使用模式V2读取记录,但出现以下错误:

org.apache.avro。AvroTypeException:找到foo,应为foo

我使用avro-1.7.3和:

   writer = new GenericDatumWriter<GenericData.Record>(SchemaV1);
   reader = new GenericDatumReader<GenericData.Record>(SchemaV2, SchemaV1);

以下是这两种模式的示例(我也尝试过添加命名空间,但没有成功)。

架构V1:

{
"name": "foo",
"type": "record",
"fields": [{
    "name": "products",
    "type": {
        "type": "array",
        "items": {
            "name": "product",
            "type": "record",
            "fields": [{
                "name": "a1",
                "type": "string"
            }, {
                "name": "a2",
                "type": {"type": "fixed", "name": "a3", "size": 1}
            }, {
                "name": "a4",
                "type": "int"
            }, {
                "name": "a5",
                "type": "int"
            }]
        }
    }
}]
}

架构V2:

{
"name": "foo",
"type": "record",
"fields": [{
    "name": "products",
    "type": {
        "type": "array",
        "items": {
            "name": "product",
            "type": "record",
            "fields": [{
                "name": "a1",
                "type": "string"
            }, {
                "name": "a2",
                "type": {"type": "fixed", "name": "a3", "size": 1}
            }, {
                "name": "a4",
                "type": "int"
            }, {
                "name": "a5",
                "type": "int"
            }]
        }
    }
},
{
            "name": "purchases",
            "type": ["null",{
                    "type": "array",
                    "items": {
                            "name": "purchase",
                            "type": "record",
                            "fields": [{
                                    "name": "a1",
                                    "type": "int"
                            }, {
                                    "name": "a2",
                                    "type": "int"
                            }]
                    }
            }]
}]
} 

提前谢谢。

共有3个答案

仉运乾
2023-03-14

最好的方法是使用模式映射来维护类似于模式的融合Avro模式注册表。

关键带走:

1.  Unlike Thrift, avro serialized objects do not hold any schema.
2.  As there is no schema stored in the serialized byte array, one has to provide the schema with which it was written.
3.  Confluent Schema Registry provides a service to maintain schema versions.
4.  Confluent provides Cached Schema Client, which checks in cache first before sending the request over the network.
5.  Json Schema present in “avsc” file is different from the schema present in Avro Object.
6.  All Avro objects extends from Generic Record
7.  During Serialization : based on schema of the Avro Object a schema Id is requested from the Confluent Schema Registry.
8.  The schemaId which is a INTEGER is converted to Bytes and prepend to serialized AvroObject.
9.  During Deserialization : First 4 bytes are removed from the ByteArray.  4 bytes are converted back to INTEGER(SchemaId)
10. Schema is requested from the Confluent Schema Registry and using this schema the byteArray is deserialized.

http://bytepadding.com/big-data/spark/avro/avro-serialization-de-serialization-using-confluent-schema-registry/

闻人英韶
2023-03-14

你可以做相反的事情。这意味着你可以解析数据模式1并从模式2写入数据。因为在写入时,它会将数据写入文件,如果我们在读取时不提供任何字段,那么它就可以了。但如果我们写入的字段少于读取的字段,那么它在读取时不会识别额外的字段,因此,它会给出错误。

谭飞掣
2023-03-14

我遇到了同样的问题。这可能是avro的错误,但您可能可以通过在“购买”字段中添加“默认”: null来解决问题。

查看我的博客了解详情:http://ben-tech.blogspot.com/2013/05/avro-schema-evolution.html

 类似资料:
  • 我正试图了解更多关于我们在Kafka主题中使用的Avro模式的信息,我对这一点相对来说比较陌生。 我想知道是否有一种方法可以在特定情况下发展模式。我们用一个不能为null的新字段或任何默认值来更新模式,因为这些新字段是标识符。解决这个问题的方法是创建新主题,但是有没有更好的方法来改进现有模式?

  • 我尝试使用avro-python3(向后兼容性)重新创建一个模式演变案例。 我有两个模式: 第二个模式没有字段,但有两个附加字段:和。 根据avro模式演化规则,如果我用schema_v1写入avro记录: …我可以使用schema_v2读取它,前提是不存在字段有默认值 但我得到了以下错误: 我知道这在Java中有效。这是一个视频课程的示例。有没有办法让它在python中工作?

  • 当我试图用一个简单的Java程序测试Avro模式演化时,我得到了一个< code>ClassCastException。 Avro版本: 你能让我知道如何解决这个错误吗?

  • 如果我使用模式版本1序列化一个对象,然后将模式更新为版本2(比如添加一个字段),那么在以后反序列化该对象时是否需要使用模式版本2?理想情况下,我只希望使用模式版本2,并使反序列化对象具有在对象最初序列化后添加到模式中的字段的默认值。 也许一些代码会更好地解释... 架构 1: 方案2: 使用通用非代码生成方法: 导致EOFException。使用会导致AvroTypeException。 我知道如

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

  • 我是Hadoop和编程的新手,我对Avro模式演变有点困惑。我将解释到目前为止我对Avro的理解。 Avro是一种串行化工具,它存储二进制数据,其json模式位于顶部。模式如下所示。 现在我的问题是为什么我们需要进化?我已经了解到,我们可以在新字段的模式中使用<code>default</code>选项;但是,如果我们在文件中添加一个新的模式,早期的模式将被覆盖。一个文件不能有两个架构。 另一个问