개발 일지

Kafka Schema Registry

북극곰은콜라 2023. 5. 23. 18:17
반응형


개요

 - Schema Registry는 Kafka와 별도로 동작하는 프로세스이며, Kafka에서 발생하는 Message에 대한 Schema를 관리하는 역할을 가진다.
 - RESTful 인터페이스로 동작한다.
 - Confluent에서 공개한 오픈소스 (Hortonworks, Spring Cloud Stream 도 있음)

Confluent Schema Registry

목적

데이터 호환성을 유지 및 관리하기 위해서 개발되었다.
producer, consumer가 많을 수 있는 분산 시스템 환경에서, 데이터에 대한 호환성을 유지하기 위함
또한 schema에 대한 관리를 하기 위함. (data governance, 정확성, 신뢰성)

장단점

장점 단점
  1. 스키마 변경 시 발생하는 오류 방지: 메시지에 대한 변경이 일어날 때 보다 안정적으로 진행 가능
  2. 중복된 스키마 방지: 스키마의 중앙관리로 중복된 스키마를 방지
  3. 호환성 검사 (유료): kafka에 발행되는 메시지를 validation 할 수 있다.
  4. 스키마 버전관리: 스키마를 여러 버전으로 관리 가능하다. 롤백 등 가능
  5. 그룹간 협업 강화: schema에 대한 공유 및 보장
  1. 관리 포인트 증가(서버): schema registry 서버를 관리해야 함
  2. 관리 포인트 증가: 엄격한 스키마 검증이 있기 때문에, 스키마에 대한 관리 필요
  3. 중앙 집중식 서비스: 확장성, 가용성 문제 발생 가능

 


Schema Registry Flow

CachedSchemaRegistryClient: Confluent에서 제공하는 Scehma registry 연동 라이브러리 안에 한 모듈, 기동 시 schema registry에 등록된 모든 schema를 캐싱하며, _schmas를 consume 해서 신규 스키마에 대한 정보를 캐싱

Schema Registry는 kafka를 storage로 사용한다.

// topic: _schemas

// schema insert message
{
  "subject": "test.message-value",
  "version": 1,
  "id": 2,
  "schema": "{\"type\":\"record\",\"name\":\"Device\",\"namespace\":\"com.example.kafkatest.data.device\",\"fields\":[{\"name\":\"id\",\"type\":\"long\"},{\"name\":\"capability\",\"type\":{\"type\":\"record\",\"name\":\"Capability\",\"namespace\":\"com.example.kafkatest.data.device.capability\",\"fields\":[{\"name\":\"name\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"value\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}}]}}]}",
  "deleted": false
}

// schema update (evolution) message
{
   "subject": "test.message-value",
   "version": 2,
   "id": 3,
   "schema": "{\"type\":\"record\",\"name\":\"Device\",\"namespace\":\"com.example.kafkatest.data.device\",\"fields\":[{\"name\":\"id\",\"type\":\"long\"},{\"name\":\"location\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"},\"default\":\"default-location\"},{\"name\":\"capability\",\"type\":{\"type\":\"record\",\"name\":\"Capability\",\"namespace\":\"com.example.kafkatest.data.device.capability\",\"fields\":[{\"name\":\"name\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"value\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}}]}}]}",
   "deleted": false
}
producer는 publish 전 Schema Registry를 통해 스키마를 등록(갱신,확장)할 수 있으며, 실패 시 메시지 생성을 안 한다.
// Schema 등록 실패
2023-04-17 16:31:46.154 ERROR 26796 --- [io-40001-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.kafka.KafkaException: Send failed; nested exception is org.apache.kafka.common.errors.InvalidConfigurationException: Schema being registered is incompatible with an earlier schema for subject "test.message-value"; error code: 409] with root cause
org.apache.kafka.common.errors.InvalidConfigurationException: Schema being registered is incompatible with an earlier schema for subject "test.message-value"; error code: 409

 


Schema Evolution 전략

각 전략마다 schema를 POST 하는데 200인지 409인지 결정됨

 


11번가 Schema Registry 도입 예시

11번가의 고민

 

DTO 의 필드가 변경되면 어떻게 될까요?
-> 필드의 타입이나 이름이 변경된다면 Consumer에서 해석하지 못하는 메시지를 Producer 가 전송하게 될 수도 있는데 막을 수 있는 방법은 조심하는 방법밖에는 없습니다.

DTO에 변경사항이 발생해서 적용할 때 배포는 Producer 쪽을 먼저 해야 하나요? Consumer를 먼저 해야 하나요?
-> 어떤 변경이 어떤 영향을 주게 될지 잘 모르겠습니다. 변경이 생길 때마다 영향범위를 체크하고 이상이 없을지 충분히 테스트하고 배포해야 합니다.

Producer 가 json 포맷으로 메시지를 serialize 해서 Kafka topic에 전달하면 topic 에는 json 프로퍼티의 key 값을 반복적으로 저장하게 될 텐데 디스크 낭비 아닌가요?
-> 낭비입니다.

Producer는 Consumer 가 해석할 수 있는 메시지만을 전달하도록 할 수는 없을까요?


Schema Evolution 전략

FULL 전략을 사용
배포 시점을 제외, 서로 다른 schema version을 사용 안 함
배포 시점에 Deserialize Exception을 방지하기 위해 FULL 전략 채용
모든 필드에 대해 default를 지정하는 컨밴션 적용

 


Conclusion

 - Schema Registry는 Kafka로 인해 끊어진 Message의 Schema를 관리 및 보장하기 위해 개발된 관리 프로세스
 - data 호환성과 관리 포인트 난이도 사이에 trade-off가 존재한다.
 - 다수의 팀이 kafka에 붙는 대형 개발사에서는 필수 요소로 손꼽힘

 


REFERENCE

 

 

반응형

'개발 일지' 카테고리의 다른 글

HttpClient (Netty) Configuration 정리  (0) 2023.05.25
Kafka Connect 사용성 검토  (0) 2023.05.24
Apache Avro 란  (2) 2023.05.22
브라우저와 Redirect (feat. XMLHttpRequest)  (0) 2023.05.19
Redis 설치 (ubuntu)  (0) 2023.04.26