책너두 (데이터 중심 애플리케이션 설계) 10일차 (~123p)
- Book/데이터 중심 애플리케이션 설계
- 2023. 3. 25.
요약
- 4장 부호화의 발전에 대한 개요를 이해함.
- 상위, 하위 호환성을 유지하기 위해서 데이터 시스템을 어떻게 지원할지 를 설명함.
- 데이터 부호화 형식을 이해하게 됨.
- 메모리 ↔ 바이트열 (= 부호화, 복호화)
- 언어별 데이터 부호화 형식이 있음.
- 내장 라이브러리에 문제가 많아서 일반적으로 좋지 않은 방법
- JSON, XML, 이진 변형 방식을 이해하게 됨.
- 표준화된 부호화 방식
- 데이터 교환 형식에 적합한 방식임.
- 더 간편하고 파싱이 빠른 형식으로 이진 부호화 방식을 선택할 수 있음.
- 스리프트와 프로토콜 버퍼에 대한 내용을 알게 됨.
- 이진 부호화 라이브러리임.
- 필드 태그와 데이터 타입에 대한 스키마 발전을 가능하게함.
메모
4장. 부호화와 발전
- 데이터 타입이나 스키마 변경될 때, 애플리케이션 코드에 대한 변경이 종종 발생함.
- 하지만 대규모 애플리케이션에서 코드 변경은 대개 즉시 반영할 수 없음.
- 서버 측 애플리케이션에서는 한 번에 몇 개의 노드에 새 버전을 배포하고, 새 버전이 원활히 실행 되는지 확인한 다음, 서서히 모든 노드에 실행되게 하는 순화식 업그레이드 (rolling upgrade = 단계절 롤아웃, staged rollout) 방식을 사용함.
- 클라이언트 측은 전적으로 사용자에 의해 좌우됨.
- 예전 버전의 코드와 새로운 버전의 코드가 시스템에 동시에 공존해야만 시스템이 원활히 양방향으로 호환성을 유지할 수 있다.
- 하위 호환성 : 새로운 코드는 예전 코드가 기록한 데이터를 읽을 수 있어야 함.
- 상위 호환성 : 예전 코드는 새로운 코드가 기록한 데이터를 읽을 수 있어야 함.
- 하위 호환성을 일반적으로 어렵지 않지만, 상위 호환성은 예전 버전의 코드가 새 버전의 코드에 의해 추가된 것을 무시할 수 있어야 하므로 다루기 어려움.
- 이번 장에서는 예전 버전과 새로운 버전의 데이터와 코드가 공존하는 시스템을 어떻게 지원하는지 설명한다.
- 하지만 대규모 애플리케이션에서 코드 변경은 대개 즉시 반영할 수 없음.
데이터 부호화 형식
- 프로그램은 보통 최소 두 가지 형태로 표현된 데이터를 사용하여 동작함.
- 메모리에 객체, 구조체, 리스트, 배열, 해시 테이블, 트리 등으로 데이터가 유지됨.
- 이러한 데이터 구조는 CPU 에서 효율적으로 접근하고 조작할 수 있게 최적화 됨(= 포인터 이용)
- 데이터를 파일에 쓰거나 네트워크를 통해 전송하려면 스스로를 포함한 일련의 바이트열 형태로 부호화 해야 함.
- 포인터는 다른 프로세스에서는 이해할 수 없기에 이러한 일련의 바이트열은 보통의 메모리에서 사용하는 데이터 구조와는 상당히 다름.
- 메모리에 객체, 구조체, 리스트, 배열, 해시 테이블, 트리 등으로 데이터가 유지됨.
- 위 두 표현 사이에 일종의 전환이 필요.
- 인메모리 표현 → 바이트열 전환을 부호화(= 직렬화, 마샬링) 이라고함.
- 바이트열 → 인메모리 표현 전환을 복호화(= 파싱, 역직렬화, 언마샬링) 이라고 함.
부호화는 암호화와 관련이 없음.
- 데이터 전환은 공통적인 문제이므로, 여러 다양한 라이브러리와 부호화 형식이 있음.
언어별 형식
- 많은 프로그래밍 언어는 인메모리 객체를 바이트열로 부호화하는 기능을 내장함.
- 자바 : Serializable
- 루비 : Marshal
- 파이썬 : pickle
- 프로그래밍 언어에 내장된 부호화 라이브러리는 심각한 문제 또한 많음.
- 부호화는 특정 프로그래밍 언어와 엮여 있어 다른 언어에서 데이터를 읽기 매우 어려움.
- 동일한 객체 유형의 데이터를 복원하려면 복호화 과정이 임의의 클래스를 인스턴스화 할 수 있어야 함.
- 이는, 보안 문제가 될 수 있음. 공격자가 임의의 바이트열을 복호화 할 수 있는 애플리케이션이 있다면, 공격자가 원격으로 임의 코드를 실행하는 끔찍한 상황이 발생할 수 있음.
- 데이터 버전 관리를 등한시하게 됨. (상위, 하위 호환성의 불편한 문제 때문..)
- 효율성(= 부호화, 복호화에 소요되는 CPU 시간과 부호화된 구조체 크기)도 나중에 생각하게 됨..
- 위 이유로, 일시적인 목적 외에는 언어에 내장된 부호화를 사용하는 방식은 일반적으로 좋지 않음.
JSON과 XML, 이진 변형
- 많은 프로그래밍 언어에서 쓸 수 있는 표준화된 부호화임.
- XML은 종종 너무 장황하고 불필요하게 복잡하다고 비판 받음.
- JSON은 XML에 비해 단순하여 인기가 있음.
- CSV도 강력하진 않지만 인기 있고, 언어 독립적 형식임.
- JSON, XML, CSV 는 텍스트 형식이여서 사람이 읽을 수 있음.
- 일부 미묘한 문제가 있음.
- 수(number) 부호화에 애매함이 있음.
- XML, CSV는 수와 숫자로 구성된 문자열을 구분할 수 없음
- JSON은 문자열과 수를 구분하지만, 정수와 부동소수점 수를 구별하지 않음.
- 이 문제는 큰 수를 다룰 때 문제가 됨.
- JSON과 XML은 유니코드 문자열을 잘 지원함.
- 그러나 이진 문자열(문자 부호화가 없는 바이트열)을 지원하지 않음.
- 따라서 이진 데이터를 Base63로 부호화하여 이런 제한을 피하지만, 정공법과 다르며, 데이터 크기도 33% 증가함.
- XML, JSON은 모두 스키마를 지원함.
- 하지만 스키마 사용을 강제하지 않기에, 데이터를 올바르게 해석하기 위해, 스키마를 사용하지 않는 애플리케이션은 필요한 부호화/복호화 로직을 하드 코딩해야할 수 있음.
- CSV는 스키마가 없으므로 로우, 칼럼의 의미를 정의하는 작업을 애플리케이션이 해야 함.
- 수(number) 부호화에 애매함이 있음.
- 위의 문제가 있음에도 다양한 용도로 사용하고 있음.
- 특히, 데이터 교환 형식으로 사용하기에 매우 좋음.
- 일부 미묘한 문제가 있음.
이진 부호화
- 조직 내에서만 사용하는 데이터라면 더 간편하고 파싱이 빠른 형식을 선택할 수 있음.
- 작은 데이터셋은 부호화 형식 선택으로 얻는 이득이 무시할 정도지만, 테라바이트 정도가 되면 데이터 타입의 선택이 큰 영향을 미침.
- JSON, XML는 둘 다 훨씬 많은 공간을 사용함.
- 이는 JSON, XML용으로 사용 가능한 다양한 이진 부호화의 개발로 이어짐.
- JSON → 메시지팩, BSON, BJSON, UBJSON, BISON, 스마일 등등
- XML → WBXML, 패스트 인포셋
- JSON/XML 데이터 모델은 테이터 타입을 변경하지 않고 유지함.
- 스키마를 지정하지 않을 수 있기에, 부호화된 데이터 안에 모든 객체의 필드 이름을 포함해야 함.
- 메시지팩을 이용한 부호화 예시는 p118, 119 에 잘 설명되어 있음.
- 이는 JSON, XML용으로 사용 가능한 다양한 이진 부호화의 개발로 이어짐.
스리프트와 프로토콜 버퍼
- 아파치 스리프트, 프로토콜 버퍼는 같은 원리를 기반으로 한 이진 부호화 라이브러리임.
- 두 라이브러리 모두 부호화할 데이터를 위한 스키마가 필요함.
- 스키마 정의를 사용해 코드를 생성하는 도구가 존재함.
- 이 도구는 다양한 프로그래밍 언어로 스키마를 구현한 클래스를 생성함.
- 스키마로 부호화된 데이터는 다음과 같음.
- 스리프트 → 바이너리프로토콜(BinaryProtocol) 과 컴팩트프로토콜(CompactProtocol)
- 프로토콜 버퍼 → 스리프트의 컴팩트프로토콜과 비슷한 방식(비트를 줄여 저장하는 처리 방식이 약간 다름)
- 부호화에 대한 예시는 p120~122 에 잘 설명되어 있음.
- 두 라이브러리 모두 부호화할 데이터를 위한 스키마가 필요함.
필드 태그와 스키마 발전
- 필연적으로 시간이 지남에 따라 스키마는 변함
- 이를 스키마 발전(schema evolution) 이라 부름
- 스리프트와 프로토콜 버퍼는 하위, 상위 호환성을 유지하면서 스키마를 변경시킬 수 있음.
- 부호화 예시에 나오듯, 부호화된 레코드는 부호화된 필드의 연결일 뿐임.
- 필드에 새로운 태그 번호를 부여하는 방식으로 스키마에 새로운 필드를 추가할 수 있음.
- 예전 코드가 새 코드로 기록한 데이터를 읽을 경우, 해당 필드를 간단히 무시할 수 있음.
- 예전 코드가 인식할 수 없는 태그 번호를 가진 필드가 포함되어 있기 때문
데이터타입과 스키마 발전
- 필드의 데이터 타입 변경은 불가능하진 않지만 값이 정확하지 않거나 잘릴 위험이 있음.
- ex) 32비트 정수를 64비트 정수로 바꿀 경우
- 저장된 데이터는 누락된 비트를 0으로 채울 수 있기에 새 코드는 예전 코드가 기록한 데이터를 쉽게 읽을 수 있음.
- 새 코드가 기록한 데이터를 예전 코드가 읽는 경우에는 32비트 변수를 계속 사용하므로 복호화된 64비트 값이 32비트와 맞지 않아 잘리게됨.
- ex) 32비트 정수를 64비트 정수로 바꿀 경우
- 프로토콜 버퍼의 경우 repeated 필드의 부호화를 통해 단일 값을 다중 값으로 변경해도 됨.
- 스리프트의 경우 전용 목록 데이터타입이 있음.
- 단일 값 → 다중 값 변경은 허용하지 않지만 중첩 목록을 지원함.
'Book > 데이터 중심 애플리케이션 설계' 카테고리의 다른 글
책너두 (데이터 중심 애플리케이션 설계) 12일차 (~147p) (0) | 2023.03.27 |
---|---|
책너두 (데이터 중심 애플리케이션 설계) 11일차 (~133p) (0) | 2023.03.26 |
책너두 (데이터 중심 애플리케이션 설계) 8일차 (~112p) (0) | 2023.03.24 |
책너두 (데이터 중심 애플리케이션 설계) 7일차 (~97p) (2) | 2023.03.22 |
책너두 (데이터 중심 애플리케이션 설계) 6일차 (~84p) (0) | 2023.03.21 |