๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Confluent Schema Registry๋กœ ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ: Avro ์Šคํ‚ค๋งˆ ์‚ฌ์šฉ ๋ฐ ๋ฒ„์ „ ๊ด€๋ฆฌ

okrestart 2024. 10. 23.

 

Confluent Schema Registry ๋Š” Kafka ๋ฐ์ดํ„ฐ์˜ ์Šคํ‚ค๋งˆ๋ฅผ ์ค‘์•™์—์„œ ๊ด€๋ฆฌ ํ•˜๊ณ , ๋ฐ์ดํ„ฐ์˜ ํ˜ธํ™˜์„ฑ์„ ๋ณด์žฅ ํ•˜๋Š” ์ค‘์š”ํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. Kafka์™€ ํ•จ๊ป˜ Avro , JSON , Protobuf ๊ฐ™์€ ๋ฐ์ดํ„ฐ ํฌ๋งท์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ์˜ ์Šคํ‚ค๋งˆ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์Šคํ‚ค๋งˆ์˜ ๋ฒ„์ „ ๊ด€๋ฆฌ ์™€ ํ˜ธํ™˜์„ฑ ์ •์ฑ… ์„ ์ ์šฉํ•˜์—ฌ ์‹œ์Šคํ…œ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Schema Registry ์˜ ์†Œ๊ฐœ์™€ ํ•จ๊ป˜, ์Šคํ‚ค๋งˆ ๋ฒ„์ „ ๊ด€๋ฆฌ ๋ฐฉ๋ฒ•, ์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ Avro ์Šคํ‚ค๋งˆ ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•, ๊ทธ๋ฆฌ๊ณ  ์Šคํ‚ค๋งˆ ์ •์ฑ… ์„ ์–ด๋–ป๊ฒŒ ์„ค์ •ํ•˜๋Š”์ง€ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค.

 


 

 

1. Schema Registry ์†Œ๊ฐœ

Schema Registry ๋Š” Kafka์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ ์Šคํ‚ค๋งˆ ๋ฅผ ์ค‘์•™์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ๊ฐ ์Šคํ‚ค๋งˆ๋Š” ๊ณ ์œ ์˜ ID ๋กœ ๋“ฑ๋ก๋˜์–ด, Kafka ํด๋Ÿฌ์Šคํ„ฐ์˜ ๊ฐ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์—์„œ ํ•ด๋‹น ์Šคํ‚ค๋งˆ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ ์„ ์œ ์ง€ํ•˜๊ณ , ๋ฐ์ดํ„ฐ ๊ฐ„์˜ ํ˜ธํ™˜์„ฑ ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Schema Registry์˜ ์ฃผ์š” ๊ธฐ๋Šฅ

  • ์Šคํ‚ค๋งˆ ์ค‘์•™ ๊ด€๋ฆฌ : ๋ชจ๋“  ์Šคํ‚ค๋งˆ๋ฅผ ํ•œ ๊ณณ์—์„œ ๊ด€๋ฆฌํ•˜์—ฌ, ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜๊ณผ ํ˜ธํ™˜์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฒ„์ „ ๊ด€๋ฆฌ : ์Šคํ‚ค๋งˆ์˜ ๋‹ค์–‘ํ•œ ๋ฒ„์ „์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ ํ๋ฆ„์—์„œ ์ƒˆ ๋ฒ„์ „์˜ ์Šคํ‚ค๋งˆ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ˜ธํ™˜์„ฑ ์ •์ฑ… : ์Šคํ‚ค๋งˆ ๊ฐ„์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ์ •์ฑ…์„ ์„ค์ •ํ•˜์—ฌ ์‹œ์Šคํ…œ ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

 


 

2. ์Šคํ‚ค๋งˆ์˜ ๋ฒ„์ „ ๊ด€๋ฆฌ์™€ ํ˜ธํ™˜์„ฑ ์œ ์ง€

Kafka ์‹œ์Šคํ…œ์—์„œ ์Šคํ‚ค๋งˆ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ, ์Šคํ‚ค๋งˆ ํ˜ธํ™˜์„ฑ ์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. Confluent Schema Registry ๋Š” ์—ฌ๋Ÿฌ ์Šคํ‚ค๋งˆ ๋ฒ„์ „ ์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๊ฐ ๋ฒ„์ „ ๊ฐ„์˜ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๋„๋ก ์ •์ฑ…์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํ‚ค๋งˆ ํ˜ธํ™˜์„ฑ ์ •์ฑ…์˜ ์ข…๋ฅ˜

  • BACKWARD : ์ƒˆ ์Šคํ‚ค๋งˆ๊ฐ€ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜๋„๋ก ๊ฐ•์ œ.
  • FORWARD : ์ด์ „ ์Šคํ‚ค๋งˆ๊ฐ€ ์ƒˆ ์Šคํ‚ค๋งˆ์™€ ํ˜ธํ™˜๋˜๋„๋ก ๊ฐ•์ œ.
  • FULL : ์–‘๋ฐฉํ–ฅ์œผ๋กœ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€.

์Šคํ‚ค๋งˆ ๋“ฑ๋ก ์˜ˆ์‹œ

curl -X POST -H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"schema": "{\"type\":\"record\",\"name\":\"User\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"age\",\"type\":\"int\"}]}"}' \
http://localhost:8081/subjects/User-value/versions

์„ค๋ช…:

  • ์œ„ ๋ช…๋ น์€ User ๋ผ๋Š” ์Šคํ‚ค๋งˆ๋ฅผ Schema Registry ์— ๋“ฑ๋กํ•˜๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.
  • ์ด ์Šคํ‚ค๋งˆ๋Š” name ๊ณผ age ํ•„๋“œ๋ฅผ ๊ฐ€์ง„ Avro ํƒ€์ž…์˜ ๋ ˆ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

์Šคํ‚ค๋งˆ ๋ฒ„์ „ ๊ด€๋ฆฌ ์˜ˆ์‹œ

curl -X GET http://localhost:8081/subjects/User-value/versions
  • ํ•ด๋‹น ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋ฉด, User ์Šคํ‚ค๋งˆ์˜ ๋ชจ๋“  ๋ฒ„์ „์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


 

3. ์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ Avro ์Šคํ‚ค๋งˆ ์‚ฌ์šฉ

์Šคํ”„๋ง ๋ถ€ํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ Avro ํฌ๋งท์„ ์‚ฌ์šฉํ•˜์—ฌ Kafka ๋ฉ”์‹œ์ง€๋ฅผ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Spring Kafka ์™€ Confluent Schema Registry ๋ฅผ ์—ฐ๋™ํ•˜๋ฉด, ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ๊ฐ€ ๋”์šฑ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.

์Šคํ”„๋ง ๋ถ€ํŠธ ์„ค์ • ์˜ˆ์‹œ

spring:
  kafka:
    bootstrap-servers: localhost:9092
    properties:
      schema.registry.url: http://localhost:8081
    consumer:
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: io.confluent.kafka.serializers.KafkaAvroDeserializer
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: io.confluent.kafka.serializers.KafkaAvroSerializer

Avro ๋ฉ”์‹œ์ง€ ์˜ˆ์‹œ

// Avro ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”์‹œ์ง€ ์ƒ์„ฑ
public class AvroProducer {
    @Autowired
    private KafkaTemplate<String, User> kafkaTemplate;

    public void sendMessage() {
        User user = User.newBuilder().setName("John Doe").setAge(30).build();
        kafkaTemplate.send("user-topic", user);
    }
}

์„ค๋ช…:

  • KafkaAvroSerializer ์™€ KafkaAvroDeserializer ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Avro ๋ฐ์ดํ„ฐ๋ฅผ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • Schema Registry URL์„ ์ง€์ •ํ•˜์—ฌ ์Šคํ‚ค๋งˆ๋ฅผ ์ค‘์•™์—์„œ ๊ด€๋ฆฌํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

 


 

4. ์Šคํ‚ค๋งˆ ์ •์ฑ… ์ ์šฉ ๋ฐฉ๋ฒ•

์Šคํ‚ค๋งˆ ํ˜ธํ™˜์„ฑ ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ ์ ˆํ•œ ์ •์ฑ… ์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ํ˜ธํ™˜์„ฑ ์ •์ฑ…์„ ์„ค์ •ํ•˜๋ฉด, ๋ฐ์ดํ„ฐ ํ๋ฆ„์—์„œ ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ ์‹œ ๋ฐ์ดํ„ฐ ์†์‹ค ์ด๋‚˜ ๋น„ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํ‚ค๋งˆ ํ˜ธํ™˜์„ฑ ์ •์ฑ… ์„ค์ • ์˜ˆ์‹œ

curl -X PUT -H "Content-Type: application/vnd.schemaregistry.v1+json" \
--data '{"compatibility": "BACKWARD"}' \
http://localhost:8081/config/User-value

์„ค๋ช…:

  • BACKWARD ํ˜ธํ™˜์„ฑ ์ •์ฑ…์„ ์„ค์ •ํ•˜์—ฌ, ์ƒˆ๋กœ์šด ์Šคํ‚ค๋งˆ ๋ฒ„์ „์ด ์ด์ „ ์Šคํ‚ค๋งˆ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

 


 

Schema Registry ํŠธ๋ Œ๋“œ ๋ฐ ํ†ต๊ณ„

Confluent Schema Registry ๋Š” ์ ์  ๋” ๋งŽ์€ ๊ธฐ์—…์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์œผ๋ฉฐ, ํŠนํžˆ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ ๊ณผ ํ˜ธํ™˜์„ฑ ์„ ์œ ์ง€ํ•ด์•ผ ํ•˜๋Š” ๋Œ€๊ทœ๋ชจ ์‹œ์Šคํ…œ์—์„œ ์ค‘์š”ํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ๊ทผ ๋ฐ์ดํ„ฐ์— ๋”ฐ๋ฅด๋ฉด, ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ ๋ฅผ ์ž๋™ํ™”ํ•œ ๊ธฐ์—…์€ ๋ฐ์ดํ„ฐ ์˜ค๋ฅ˜ ๊ฐ€ 50% ์ด์ƒ ๊ฐ์†Œํ•˜๊ณ , ์‹œ์Šคํ…œ ์—…๊ทธ๋ ˆ์ด๋“œ ๊ณผ์ •์—์„œ ๋ฐ์ดํ„ฐ ์†์‹ค ์ด ๊ฑฐ์˜ ์—†์—ˆ๋‹ค๊ณ  ๋ณด๊ณ ๋ฉ๋‹ˆ๋‹ค.

 


 

์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธ (FAQ)

Q1. Schema Registry๋Š” ์™œ ํ•„์š”ํ•œ๊ฐ€์š”?
A1. Schema Registry ๋Š” Kafka์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์Šคํ‚ค๋งˆ๋ฅผ ์ค‘์•™์—์„œ ๊ด€๋ฆฌ ํ•˜๊ณ , ๋ฐ์ดํ„ฐ์˜ ํ˜ธํ™˜์„ฑ ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ , ์‹œ์Šคํ…œ ๊ฐ„ ๋น„ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Q2. ์Šคํ‚ค๋งˆ ํ˜ธํ™˜์„ฑ ์ •์ฑ…์€ ์–ด๋–ป๊ฒŒ ์„ค์ •ํ•˜๋‚˜์š”?
A2. Schema Registry ์—์„œ ์ œ๊ณตํ•˜๋Š” API๋ฅผ ํ†ตํ•ด BACKWARD , FORWARD , FULL ๋“ฑ์˜ ํ˜ธํ™˜์„ฑ ์ •์ฑ…์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ ์‹œ์—๋„ ์‹œ์Šคํ…œ์˜ ์•ˆ์ •์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Q3. ์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ Avro ์Šคํ‚ค๋งˆ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•˜๋‚˜์š”?
A3. Spring Kafka ์™€ Schema Registry ๋ฅผ ์—ฐ๋™ํ•˜์—ฌ, KafkaAvroSerializer ์™€ KafkaAvroDeserializer ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Avro ์Šคํ‚ค๋งˆ๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Schema Registry URL์„ ์„ค์ •ํ•˜์—ฌ ์Šคํ‚ค๋งˆ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Q4. ์Šคํ‚ค๋งˆ์˜ ๋ฒ„์ „ ๊ด€๋ฆฌ๋Š” ์–ด๋–ป๊ฒŒ ์ด๋ฃจ์–ด์ง€๋‚˜์š”?
A4. Schema Registry ๋Š” ๊ฐ ์Šคํ‚ค๋งˆ์— ๋Œ€ํ•ด ๋ฒ„์ „ ๊ด€๋ฆฌ ๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ ์‹œ ์ƒˆ๋กœ์šด ๋ฒ„์ „์„ ๋“ฑ๋กํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„์ „ ๊ฐ„ ํ˜ธํ™˜์„ฑ ์ •์ฑ… ์„ ์„ค์ •ํ•˜์—ฌ ์Šคํ‚ค๋งˆ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Q5. Schema Registry๋ฅผ ํ†ตํ•ด ์–ด๋–ค ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‚˜์š”?
A5. Schema Registry ๋Š” ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ ์œ ์ง€ , ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ ๋ฐฉ์ง€ , ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ ์ž๋™ํ™” ์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‹œ์Šคํ…œ ๊ฐ„ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์•ˆ์ •์ ์œผ๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํฌ์ŠคํŒ…์—์„œ๋Š” Confluent Schema Registry ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ ์™€ ํ˜ธํ™˜์„ฑ ์œ ์ง€ ๋ฐฉ๋ฒ•์„ ๋‹ค๋ค˜์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Kafka ์‹œ์Šคํ…œ์—์„œ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ , ์ƒˆ๋กœ์šด ์Šคํ‚ค๋งˆ๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ๋„์ž…ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋Œ“๊ธ€