Подтвердить что ты не робот

Эволюция схемы Avro

У меня есть два вопроса:

  • Можно ли использовать те же записи чтения и разбора, которые были написаны с двумя схемами, которые совместимы, например. Schema V2 имеет только дополнительное необязательное поле по сравнению с Schema V1, и я хочу, чтобы читатель понял их? Я думаю, что ответ здесь нет, но если да, как мне это сделать?

  • Я пробовал записывать запись с Schema V1 и читать ее с помощью Schema 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"
                            }]
                    }
            }]
}]
} 

Спасибо заранее.

4b9b3361

Ответ 1

Я столкнулся с той же проблемой. Это может быть ошибкой avro, но вы, вероятно, можете обойтись, добавив "default": null в поле "покупка".

Проверьте мой блог для деталей: http://ben-tech.blogspot.com/2013/05/avro-schema-evolution.html

Ответ 2

Вы можете сделать что-то противоположное. Вы можете проанализировать схему данных 1 и записать данные из схемы 2. Beacause во время записи записывает данные в файл, и если мы не предоставляем какое-либо поле во время чтения, это будет нормально. Но если мы будем писать меньше поля, чем читать, то оно не будет распознавать дополнительное поле во время чтения, поэтому оно даст ошибку.

Ответ 3

Лучший способ - иметь сопоставление схемы для поддержки схемы, такой как реестр Confluent Avro.

Key Take Aways:

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/