[데이터 중심 애플리케이션 설계] 4. 부호화와 발전

succeeding·2024년 11월 23일
0
post-thumbnail

목표

  • JSON, XML, Protocol Buffers, Thrift, Avro 등 데이터 부호화(encoding) 혹은 직렬화(serialization) 에 대해 알아본다.
  • 각 부호화 형식이 어떻게 하위 호환성과 상위 호환성을 지원하는지 설명한다.
  • REST, RPC, message queue 에서 데이터 부호화 형식이 데이터 저장과 통신에 어떻게 사용되는지 살펴본다.

내용

데이터 부호화 형식

Language-Specific Formats

java.io.Serializable 같은 java 의 내장 직렬화는 성능이 좋지 않고 비대해지곤 한다. 이런 이유로, 언어에 내장된 부호화를 사용하는 것은 보통 좋지 않다.

JSON 과 XML, 이진 변형

결함

  • JSON 은 정수와 부동소수점 수를 구별하지 않으며, 정밀도를 지정하지 않는다. 2^53 보다 큰 정수는 IEEE 754 부동소수점 수에서는 정확하게 표편할 수 없다. 이로 인해, 부동소수점 수를 사용하는 언어에서는 파싱할 때 수가 부정확해질 수있다.
  • JSON, XML은 이진 문자열(byte array)를 지원하지 않는다. 보통 이진 데이터를 Base64 를 사용해 텍스트로 encoding 하여 이런 제한을 피한다. 이 방법은 다시 Base64 로 decoding 해야하고, 데이터 크기가 33% 증가한다는 단점이 있다.
  • JSON 과 XML 을 정의하는 스키마 언어가 있지만 익히고 구현하기가 상당히 난해하다.

그럼에도 JSON, XML, CSV 는 다양한 용도에서 사용하기 충분하고, 앞으로도 인기가 많을 것이다.

이진 부호화

JSON, XML 은 이진 형식에 비해 더 많은 공간을 사용한다. 이에 따라 JSON, XML 용의 다양한 이진 부호화(binary encoding) 개발이 이루어졌다.

그러나 JSON 과 XML 의 텍스트 버전처럼 널리 채택되지 않았다. 이진 부호화가 가독성을 떨어뜨리는 것에 비해 텍스트 부호화에 비해 공간을 절약하는 정도가 그리 크지 않다는 의견이다.

Thrift 와 Protocol Buffers

Apache Thirft(by Facebook) 와 Protocol Buffers(protobuf, by Google) 는 같은 원리를 기반으로 한 이진 부호화 라이브러리이다.

스키마를 정의하면, 해당 스키마로 다양한 프로그래밍 언어로 스키마를 구현한 클래스를 생성한다. 이 클래스로 스키마의 레코드를 이진 부호화/복호화할 수 있다.

부호화된 데이터는 필드의 이름이 아닌 스키마에서 필드에 정의한 숫자인 필드 태그(field tag) 를 사용한다. 이를 통해 부호화된 데이터의 크기를 더욱 줄일 수 있다.

Thrift 에는 바이너리프로토콜과 컴팩트프로토콜이 있다. 둘 다 이진 부호화지만 컴팩트프로토콜이 더 적은 용량을 사용한다. Protobuf 는 Thrift 의 컴팩트 프로토콜과 비슷한 정도의 용량을 사용한다.

필드 태그와 스키마 발전

스키마가 시간이 지남에 따라 변하는 것을 스키마 발전(schema evolution) 이라고 한다.

Thrift 와 Ptotobuf 에서 어떻게 상위호환성/하위호완성을 달성하면서 스키마 발전을 할 수 있을까?

필드명 수정
부호화된 데이터엔 필드명이 없고 필드 태그만 있기 때문에, 필드 태그는 수정하지 않되, 해당 태그의 필드명을 스키마에서 수정할 수 있다.

필드 추가
필드에 새로운 태그 번호를 부여하여 스키마에 새로운 필드를 추가할 수 있다.

상위 호환성 달성 필드 추가
새로 추가된 태그 번호는 이전 스키마를 가지고 있는 예전 코드에선 단순히 부호화에서 누락시키기 때문에, 상위호환성을 달성할 수 있다.

하위 호환성 달성 필드 추가
새로운 필드에 required 를 사용해선 안된다. required 를 사용하면, 새로운 스키마를 가지고 있는 새 코드가 옛 스키마의 데이터 복호화에 실패하고 만다. required 가 아닌 optional 이나 기본값으로 새로운 필드를 추가해야한다.

필드 삭제
필드 삭제는 필드를 추가할 때, 하위 호환성/상위 호환성 문제를 해결하는 방식과 반대로 하면 된다. 즉, optional 필드만 삭제할 수 있고 같은 태그 번호는 절대 다시 사용할 수 없다.

데이터 타입과 스키마발전

필드의 데이터 타입을 바꾸는 것은 위험하다.
32 비트 정수를 64 비트 정수로 바꾸는 것은 하위 호환성을 가능하나 상위 호환성은 깨지게 된다.

Protobuf 에서 optional 표시자를 repeated 로 변경하는 것은 상위 호환성과 불안전한 하위 호환성을 만족시킬 수 있다. repeated 는 같은 필드가 여러번 부호화 데이터에 나타날 수 있다는 것을 의미하며 프로그래밍 언어에서는 배열로 표시된다. optional 필드가 레코드에 존재하지 않으면 repeated 에서는 원소가 없는 배열로 읽게 되는 것이다. optional 을 사용한 예전 코드에서는 원소 중 마지막 원소만 보게 된다.

Avro

2009 년 하둡의 하위 프로젝트로 시작
읽기, 쓰기 스키마 두 개를 사용
샘플의 부호화 크기는 32바이트로 가장 작다.

아브로의 핵심아이디어

  • 쓰기 스키마와 읽기 스키마가 동일하지 않아도 되며, 단지 호환 가능하기만 하면 됨
  • 복호화(읽기)할 때, 쓰기 스키마에서 읽기 스키마로 데이터를 변환해 그 차이를 해소함

스키마 해석(resolution)

  • 이름으로 필드를 일치시키기 때문에, 쓰기 스키마와 읽기 스키마의 필드 순서가 달라도 문제 없음
  • 쓰기 스키마에만 존재하는 필드는 읽기에서 무시 됨
  • 읽기 스키마에만 존재하고 데이터에 해당 필드가 없는 경우 기본값으로 채움

스키마 발전 규칙

아브로의 상위 호환성

  • 새로운 버전의 쓰기 스키마를 이전 버전의 읽기 스키마로 읽을 수 있음

아브로의 하위 호환성

  • 이전 버전의 쓰기 스키마를 새로운 버전의 읽기 스키마로 읽을 수 있음

호환성을 유지하기 위해서는, 기본값이 있는 필드만 추가하거나 삭제할 수 있다.

스키마의 장점

Modes Of Dataflow

Dataflow Through Databases

Dataflow Through Services: REST and RPC

Message-Passing Dataflow

0개의 댓글