2013-03-11 2 views
11

나는 두 가지 질문이 있습니다아 브로 스키마 진화

  1. 이 가능 같은 리더를 사용하고 호환, 예를 들어, 두 개의 스키마로 작성된 기록을 분석하는 것입니다 Schema V2Schema V1과 비교하여 추가 필드를 가질 수 있습니다. 나는 대답이 '아니오'라고 생각하지만 그렇다면 어떻게해야합니까?

  2. 내가 Schema V1로 기록을 작성하고 Schema V2로 읽기 시도했다, 그러나 나는 다음과 같은 오류가 발생합니다 :

    org.apache.avro.AvroTypeException : 기대, foo는 찾을 수 foo는

나는 아 브로-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" 
          }] 
        } 
      }] 
}] 
} 

감사합니다.

답변

9

동일한 문제가 발생했습니다. avro의 버그 일 수도 있지만 "구입"필드에 null을 추가하면 해결할 수 있습니다.

이 내용은 내 블로그를 확인하십시오 http://ben-tech.blogspot.com/2013/05/avro-schema-evolution.html

+5

기본 값은 필수입니다. 판독기 스키마에는 있지만 작성기 스키마에는없는 필드에 기본값을 제공하지 않으면 Avro는 구문 분석 된 구조에서이 새 필드를 작성하는 방법을 알 수 없습니다. – LiMuBei

0

당신은 그것의 반대를 할 수 있습니다. 데이터 스키마 1을 구문 분석하고 스키마 2에서 데이터를 쓸 수 있다는 것을 의미합니다. 쓰기 시간에 Beacause는 파일에 데이터를 쓰고 읽는 시간에 필드를 제공하지 않으면 ok가됩니다. 그러나 우리가 읽기보다 적은 필드를 쓰는 것은 읽는 시간에 여분의 필드를 인식하지 못하기 때문에 오류를 줄 것입니다.

0

가장 좋은 방법은 Confluent 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/