Kafka/Schema-Registry

Schema-Registry?

재심 2022. 10. 31. 20:51

목차

    [Overview]

    Schema Registry는 메타데이터에 대한 서비스를 제공한다.

    Schema Registry는 Avro, JSON, Protobuf 스키마를 저장하고 검색할 수 있는 RESTful 인터페이스를 제공한다. 

    특화된 subject name strategy를 기반으로 모든 스키마의 버전을 기록하고, 다양한 compatibility 세팅과 정의된 compatibility를 바탕으로 schema evolution을 허용한다. 

     

    Schema Registry는 Kafka Broker와는 분리되어 있다.

    Producer와 Conumer는 메시지를 쓰기위해 여전히 Kafka와 통신하게 된다. 이와 동시에 Schema Registry와 통신하여 메시지의 데이터 모델을 describe하는 스키마를 보내고 검색할 수 있다. 

    Schema-Registry

    Schema Registry는 kafka를 기본 스토리지로 사용하는 스키마를 위한 것이다.

    설계를 위해 몇가지 핵심 설계사항이 있다.

     

    • 등록된 각각의 스키마에는 고유한 ID가 할당된다. 이는 고유하고 단조롭게 (monotonically) 증가하지만 반드시 연속적인 값은 아니다.
    • Kafka는 지속적으로 Backend환경을 제공하며, Schema Registry와 스키마를 포함하는 write-ahead change logging (WAL) 기능을 한다. 
      • WAL이란 DB에서 원자성과 내구성을 지원하는 기술의 한 계열로 WAL을 사용하는 시스템에서 모든 수정은 적용전에 로그에 기록되는데, 시스템에 장애가 발생할 경우 이 로그를 분석해서 현재까지 이뤄진작업과 앞으로 할 작업을 분석하여 앞으로 해야할 작업만 진행할 수 있도록 하는 것 
    • Schema Registry는 SIngle Primary Architecture로 배포되도록 설계되어 있으며 Zookeeper/Kafka는 configuration을 기반으로 primary election을 조정(coordinate)한다.

     

    [Schema, Subject 그리고 Topic]

    먼저 용어를 빠르게 리뷰하고, 이게 Schema Registry의 문맥에서 어떻게 맞춰지는지 확인해본다.

     

    Kafka는 key-value 기반의 메시지를 가진다. 그리고 이 메시지는 Avro, JSON, protobuf로 serialize할 수 있다. 

    스키마는 데이터 포맷의 구조를 정의한다. 

    kafka의 토픽명은 schema 이름과 독립적일 수 있다.

    subject는 스키마가 evolve할 수 있는 범위를 정의한다. 

    subject name은 설정된 subject name strategy에 따라 달라지며, 디폴트 값은 topic name strategy이다.

     

    [Kafka Serializers and Deserializers Background]

    네트워크를 통해 데이터를 전송하거나 파일에 저장할 때 데이터를 바이트로 인코딩 할 필요가 있다. 

    serialization은 역사를 길게 가지고 있지만 지난 몇년 동안 크게 발전하였다. 

    사람들은 Java serialization 같은 프로그래밍 serialization부터 시작하였고, 이는 이를 consuming하는 다른 언어의 불편함을 초래하고 말았다.

    → 이에 구에 받지 않는 JSON으로 통일되기 시작했다.

     

    엄격하게 정의된 포맷을 가지고있지 않다면 2가지의 단점이 있다.

    • 데이터를 소비하는 측에서 데이터 생산자를 이해하지 못할 수 있다. 또한 데이터에 필드가 임의로 추가, 삭제 될 수 있어서 데이터 소비자는 더 힘들어진다. 이러한 일이 반복되면 조직에서 이를 관리하는 것이 매우 어려워 진다. 
    • 오버헤드와 다변 (verbosity): 필드명과 타입정보가 serialized 포맷에 명시적으로 표현되어야하기 때문에 매우 장황할 수 있다. (모든 메시지에서 다 똑같더라도 메시지에 이런 정보를 다 실어야 한다)

     

    데이터 구조를 스키마에 의해 공식적으로 정의해야하는 몇 개의 cross-language serialization 라이브러리가 등장했다. (Avro, Thrift, Protocol Buffers, JSON) 

    스키마를 갖는다는 것은 데이터의 구조, 유형,의미를 명확하게 정의한다는 장점이 있고, 스키마를 사용하면 데이터를 보다 효율적으로 인코딩할 수 있다. 

     

    Avro는 Confluent Platform에서 지원되는 기본 형식이다.

    예를 들어, 아래에서는 Avro Schema는 데이터 구조를 JSON 형식으로 정의하고, 두가지 필드와 함께 user이름을 가진 record type을 정의한다.

    • name (String)
    • favorite_number (int)
    {
     "namespace": "example.avro",
     "type": "record",
     "name": "user",
     "fields": [
         {"name": "name", "type": "string"},
         {"name": "favorite_number",  "type": "int"}
     ]
    }

     

    Avro는 serialization뿐만아니라 deserialization에서는 스키마가 필요한데, 스키마는 디코딩시에도 제공되기 때문에 필드이름과 같은 메타데이터를 명시적으로 인코딩할 필요가 없기 때문이다.

    즉, 이를 통해 데이터의 binary 크기를 매우 작게 만들게 된다.  

     

    [Avro, JSON 그리고 Protobuf 지원 형식 및 확장성]

    avro는 Confluent platform에서 기본적으로 선택되었고, Kafka Serializer, deserializer가 함께 제공되었다. 

    추가로 JSON, Protobuf를 지원한다. 이 같은 새로운 serialization 포맷은 Schema Registry가 국한되지 않고 Confluent Platform 전체에 제공된다. 

    또한 custom 스키마 포맷을 지원할 수 있도록 확장도 가능하다.

     

    새로운 Kafka serializer와 deserializer는 Avro, Protobuf, JSON schema에 사용할 수 있다. 

    serializer는 Protobuf, JSON을 직렬화 할 때 스키마를 자동으로 등록할 수 있다. 

    Protobuf serializer는 가져온 모든 스키마를 반복적으로 등록할 수 있다.

     

     

    [Schema ID Allocation]

    Schema ID 할당은 항상 primary node에서 수행되며 항상 단조롭게 (monotonically) 증가한다. 

    Kafka Primary election에서 Schema ID는 항상 Kafka store에 마지막으로 쓰여진 ID를 기반으로 한다. 

    Primary 재선거가 발생하는 동안 배치 할당은 새 Primary가 (kafkastore.topic)의 모든 레코드를 따라잡은 후에 수행된다. 

     

     

    [Kafka Backend]

    Kafka는 Schema Registry의 스토리지 백엔드로 사용된다. 

    스페셜 토픽인 <kafkastore.topic) (기본값 _schema, single partition)은 가용성 높은 선행 로그 (write-ahead log)로 사용된다. 

    모든 schema, subject, version, ID metadata 그리고 compatibility 세팅이 여기에 메시지로 추가된다. 

    Schema Registry는 _schema 토픽에 메시지를 producer하고 consume하게 된다.

     

    예를 들어, 새로운 스키마가 subject로 등록되거나 compatibility 설정이 업데이트 될 때 Schema Registry의 백그라운드 스레드가 _schema 에서 consume해서 그 로컬 캐시를 업데이트 한다. 

     

    [Single Primary Architecture]

    Schema-Registry

    Schema Registry는 Single Primary Architecture를 사용하여 분산 서비스로 동작하도록 설계되었다.

    이러한 구성에서는 "주어진 순간"에 최대 하나의 Schema Registry 인스턴스가 primary가 된다.

    Primary만 카프카에 writing를 할 수 있지만 다른 노드들은 read요청을 직접 처리할 수 있다. 

    Secondary 노드들은 단순히 registration 요청을 현재 primary노드에 넘겨주고 primary에서 반환한 응답을 다시 리턴함으로써 간접적으로 등록요청을 처리하게 된다. 

     

    Confluent 4.0부터는 primary election이 Kafka group 프로토콜을 기반으로 이루어진다. 

    (Confluent 7.0에서는 Zookeeper 기반의 election이 제거되었다)

     

    [Kafka Coordinator Primary Election]

     

     

    Kafka 기반의 election은 kafkastore.connection.url이 아니라 kafkastore.bootstrap.servers가 정의되어 있을 때 사용된다.

    Kafka group 프로토콜은 leader.eligibility=true인 노드 중에서 primary를 선택한다. 

     

    [High Availability for Single Primary Setup]

    Confluent Platform의 많은 서비스들은 효과적으로 비저장상태 (stateless) (kafka에 상태를 저장하고 시작할 때 이를 로드하는 방식) 로 유지되며, 요청을 자동으로 리다이렉트 할 수 있다.

    이러한 서비스 방식은 multiple instance를 배포함으로서 손쉽게 높은 가용성을 얻을 수 있게 해준다.

    모든 노드는 READ를 처리할 수 있고, WRITE요청은 primary로 넘겨서 처리된다.

     

    추천되는 접근 방법은 하나의 가상IP 혹은 라운드로빈 DNS에 여러개의 인스턴스를 배치하고, Schema Registry 클라이언트의 schema.registry.url에 url을 정의하여 Schema Registry의 모든 인스턴스를 사용하는 것이다.

     

     

    [소스분석]

    https://github.com/confluentinc/schema-registry

     

    GitHub - confluentinc/schema-registry: Confluent Schema Registry for Kafka

    Confluent Schema Registry for Kafka. Contribute to confluentinc/schema-registry development by creating an account on GitHub.

    github.com

     

    KafkaStore

    _schemas 토픽을 관리하는 영역

    https://github.com/confluentinc/schema-registry/blob/master/core/src/main/java/io/confluent/kafka/schemaregistry/storage/KafkaStore.java

     

    GitHub - confluentinc/schema-registry: Confluent Schema Registry for Kafka

    Confluent Schema Registry for Kafka. Contribute to confluentinc/schema-registry development by creating an account on GitHub.

    github.com

     

    KafkaStoreReaderThread

    _schemas 토픽으로부터 스키마를 읽는 영역

    https://github.com/confluentinc/schema-registry/blob/master/core/src/main/java/io/confluent/kafka/schemaregistry/storage/KafkaStoreReaderThread.java

     

    [참조]

    https://docs.confluent.io/platform/current/schema-registry/index.html

     

    Schema Registry Overview | Confluent Documentation

    Home Platform Schema Management Schema Registry Overview Looking for Schema Management Confluent Cloud docs? You are currently viewing Confluent Platform documentation. If you are looking for Confluent Cloud docs, check out Schema Management on Confluent C

    docs.confluent.io

     

    'Kafka > Schema-Registry' 카테고리의 다른 글

    Schema-Registry Naming Strategy  (0) 2023.05.05
    Schema-Registry Compatibility  (0) 2022.10.31
    Schema-Registry + Validation  (0) 2022.10.31
    Schema-Registry : Consumer  (0) 2022.10.31
    Schema-Registry : Producer  (0) 2022.10.31