Avro GenericRecord,SpecificRecord

분류없음 2018.04.16 09:47 posted by dev.bistro

GenericRecord

File/String 기반의 Schema 에서 Avro Object를 생성하는 것을 말한다.  이 방법은 runtime 에서 실패할 수 있기 때문에 사용에서는 추천되는 방법은 아니지만, 쉽게 사용 할 수 있는 장점이 있다.

Schema

{
"type": "record",
"namespace": "com.example",
"name": "user",
"fields": [
{
"name": "name",
"type": "string"
}
]
}다시피 


GenericRecordBuilder builder = new GenericRecordBuilder(schemaString);
builder.set("name", "bistros");
GenericData.Record bistros = builder.build();
System.out.println(bistros);
System.out.println(bistros.getSchema());
// {"name": "bistros"}
// {"type":"record","name":"user","namespace":"com.example", "fields":[{"name":"name","type":"string"}]}

보시다시피  GenericRecordBuilder set(String fieldName, Object value) 를 통해서 값을 셋팅하기 때문에 불안하다.


SpecificRecord

그에 반해서 SpecificRecord 역시 Avro Object 이지만  Avro Schema에 의해 성성되는 코드가 좀 더 포함되어 있다.
GenericRecordBuilder builder()는 Record type을 반환하는 데  그 내부를 보면, Map<String, Object>와 다름이 없다는 것을 확인 할 수 있다.
- GenericRecord 인터페이스를 구현 ( get/put만 있다)
- 내부적으로 Object[] 만을 가지고 있다.
링크 : https://github.com/apache/avro/blob/master/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java#L178

하지만 SpecificRecord는 좀 다르다.  avro schema를 기반으로 maven/gradle 플러기인으로 resources를 생성해보면  extends org.apache.avro.specific.SpecificRecordBase 를 통해서 똑같이 GenericData를 상속하고 있지만  6개 필드를 가진 Avro Schema 파일에서 약 550라인의 Class파일이생성된다. getter/setter/builder 등이 구현되어 있다.


요약)

Gradle Plugin을 이용해서 Class 파일을 만들어야 하지만 SpecificRecord를 사용하는 게 당연하다.


사족)

Confluent의 Kafka-Avro-Serializer는 default로 generic type을 읽고 쓰게 되어 있다.

properties.setProperty("specific.avro.reader", "true");

을 통해서 specific 모드를 활성화 해야 하고,  이것을 활성화 하면 내부적으로 사용하는 DatumReader를  SpecificDatumReader 으로 셋팅하다.

추가적으로 Streams 모드를 위해서는 아예  GenericAvroSerde, SpecificAvroSerde 2개의 Serde를 따로 제공해주고 있다.




티스토리 툴바