4장. 부호화와 발전 (Encoding & Evolution)

2025. 9. 6. 12:59·Book/데이터 중심 애플리케이션 설계

 

 

❐ 0. Description


  • 데이터 부호화를 위한 다양한 형식을 살펴본다.
  • 스키마를 변경하고 "예전 버전"과 "새로운 버전의 데이터와 코드"가 공존하는 시스템을 어떻게 지원하는지 설명
  • 메시지 전달 시스템에서 다양한 데이터 부호화 형식이 데이터 저장과 통신에 어떻게 사용되는지 설명

 

 

 

❐ 1. 데이터 부호화 형식(Formats of Encoding data)


  • 프로그램은 보통 두 가지 형태로 표현된 데이터를 사용해 동작
  •  두 가지 표현 사이에 전환이 필요함
    • 부호화
      • 인메모리 표현 ➔ 바이트열
      • "직렬화" or "마샬링"이라고도 함.
    • 복호화
      • 바이트열 ➔ 인메모리 표현
      • "파싱" or "역직렬화" or "언마샬링" 이라고도 함.

 

🌀 1-1. 언어별 형식 (Language-Specific Formats)

많은 프로그래밍 언어는 부호화 기능을 내장.
  • java.io.Serializable 등등

 

매우 편리하지만, 언어에 내장된 부호화를 사용하는 방식은 일반적으로 좋지 않음!
  1. 프로그래밍 언어에 종속적임
    •  다른 언어에서 데이터를 읽기개 매우 어려움
    • 다른 시스템과 통합하는데 방해가 될 수 있음.
  2. 인스턴스화
    • 동일한 object types 데이터를 복원하려면,
            복호화 과정에서 임의의(arbitrary) 클래스를 인스턴스화 할 수 있어야 함.
    • 종종 보안 문제의 원인이 됨.
  3. 호환성
    • 데이터 버전 관리는 보통 부호화 라이브러리엣어는 나중에 생각하게 됨.
  4. 효율성
    • 자바의 내장 직렬화는 성능이 좋지 않고 비대해지는 부호화로 유명함.

 

 

🌀 1-2. JSON과 XML, 이진 변형 (JSON, XML, and Binary Variants)

  • JSON, XML, CSV는 텍스트 형식이라서, 어느 정도 사람이 읽을 수 있음.
  • 하지만 피상적인(겉으로 드러나는) 문법적 문제 외에도 일부 미묘한 문제가 있음

 

JSON, XML, CSV의 미묘한(감지하기 힘든, subtle) 문제점들
  1. 수(Number)의 부호화에는 많은 애매함이 있음.
    • XML과 CSV는 숫자(digit)와 문자 구분 불가 → 정수/부동소수점 구분 X, 정밀도 지정 X.
    • JSON은 숫자와 문자열을 구분하지만 정수/부동소수점 구분 X, 정밀도 지정 X.
    • 큰 수 표현 문제:
      • IEEE 754 부동소수점 한계로 2^53보다 큰 정수는 정확히 표현 불가.
      • 예: 트윗 ID(64비트 숫자) → 자바스크립트에서 부정확할 수 있음.
      • JSONE 같은 개선안: 숫자를 문자열(10진수)로 표현 → 정밀도 문제 해결.
  2. JSON / XML의 특징
    • JSON / XML은 텍스트(유니코드) 중심 → 사람이 읽고 쓰기 쉽다.
    • 하지만 원시 데이터(바이너리) 지원 부족 → Base64 인코딩으로 해결.
      • 단점: 크기 33% 증가, 디코딩 필요.
    • XML은 문법이 복잡하고 스키마 정의가 어려움.
    • JSON은 간단하지만 스키마를 강제하지 않음 → 데이터 무결성 검증이 어려움.
    • 따라서 애플리케이션에서 별도 부호화·복호화 로직 필요할 가능성 높음.
  3. CSV의 한계
    • 스키마 없음 → 열(column)의 의미 정의가 애플리케이션에 의존.
    • 새로운 컬럼 추가나 변경이 어려움 (수동 코드 수정 필요).
    • 매우 모호한 형식:
      • 값에 쉼표 포함 시 처리 복잡.
      • 이스케이핑 규칙은 존재하지만 구현이 제각각.
    • 결국 CSV는 단순하지만 호환성과 정밀성 부족.

 

이진 부호화
  • 데이터를 이진수(0과 1의 비트)로 표현하는 방식
  • JSON보다 공간 절약 효과는 크지 않음.
  • 장점은 속도 향상과 바이너리 지원.
  • 하지만 key 이름 그대로 포함 → 데이터 크기 절약 효과 제한.
  • 따라서 텍스트 JSON 대비 가치가 크다고 단언하기 어려움.

 

 

 

 

🌀 1-3 스리프트와 프로토콜 버퍼

아파치 스리프트 & 프로토콜 버퍼
  • 같은 원리를 기반으로 한 이진 부호화 라이브러리
  • 스리프트는 두 가지 다른 이진 부호화 형식을 지원함
    • Binary Protocol, CompactProtocol

 

필드 태그와 스키마 발전
  • 필드 태그는 절대 변경 불가
    • 기존의 모든 부호화된 데이터를 인식 불가능하게 만들 수 있기 때문
    • 필드에 새로운 태그 번호를 부여하는 방식으로 스키마엠 새로운 필드 추가할 수 있음.

 

데이터 타입과 스키마 발전
  • 32비트 정수 → 64비트 정수로 변경한다면?
    • 옛 코드는 새로운 값을 읽을 수 없음 (32비트 크기 한계).
    • 따라서 호환성 깨짐.
  • 프로토콜 버퍼는
    • 목록 타입(repeated) 지원 → 배열처럼 여러 값 가질 수 있음.

 

🌀 1-4. 아브로

아브로 
  • 또 다른 이진 encoding format
  • 두 개의 스키마 언어 있음.
    1. Avro IDL 기반
    2. JSON 기반
  • 스키마에 태그 번호 없음.
  • 스키마에 나타난 순서대로 필드를 살펴봐야 함.

 

쓰기 스키마와 읽기 스키마

 

  • 쓰기 스키마: 데이터를 쓸 때 사용되는 스키마
  • 읽기 스키마: 데이터를 복호화 할 때 기대하는 특정 스키마
  • 불일치 시 처리 규칙
    1. 쓰기에는 있지만 읽기에는 없는 필드 → 무시.
    2. 읽기에는 있지만 쓰기에는 없는 필드 → 기본값으로 채움.
    3. 타입 불일치 → 가능한 경우 자동 변환.

 

 

스키마 발전 규칙
  1. 기본값 있는 필드만 추가/삭제 가능.
  2. 기본값 없는 필드 추가/삭제 → 호환성 깨짐.
  3. Null 허용하려면 유니온(Union) 타입 사용.
  4. Avro는 optional/required 대신 유니온 타입 + 기본값.
  5. 필드 타입 변경은 제한적으로만 가능.
  6. 필드 이름 변경 시 alias로 하위 호환성 유지 가능.

 

그러면 쓰기 스키마는 무엇인가.

 

  • 모든 레코드에 스키마 전체를 포함하면 공간 낭비 심함.
  • 어떤 아브로를 사용하는지에 의존함
    • 많은 레코드가 있는 대용량 파일
    • 개별적으로 기록된 레코드를 가진 데이터베이스
    • 네트워크 연결을 통해 레코드 보내기

 

 

동적 생성 스키마

 

  • 아브로는 스키마에 태그 번호가 없음.
    • 아브로는 필드 이름 기반 매칭, 프로토콜 버퍼/스리프트는 태그 번호 기반 매칭.
    • DB 컬럼이 변해도 Avro 스키마 자동 갱신 가능

 

 

코드 생성과 동적 타입 언어
  • 스리프트와 프로토콜 버퍼는 코드 생성에 의존
  • 반면, 동적 타입 프로그래밍 언어에서는 컴파일 시점에 타입 검사기가 없어
    • 코드를 생성하는 것은 중요하지 않음.
  • 아브로는 정적 타입 프로그래밍 언어를 위해 코드 생성을 선택적으로 제공함.
    • 물론 코드 생성 없이도 사용할 수 있음.

 

 

🌀 1-5. 스키마의 장점

  1. 간단하고 자세한 유효성 검사 규칙을 지원
  2. 많은 데이터 시스템이 이진 부호화를 독자적으로 구현

 

이진 부호화의 좋은 속성
  1. 공간 절약
  2. 유용한 문서화 형식
  3. 호환성
  4. 정적 타입 프로그래밍 언어 지원

 

 

 

 

 

❐ 2. 데이터플로 모드


  • 데이터플로는 매우 추상적인 개념
  • 하나의 프로세스에서 다른 프로세스로 데이터를 전달하는 방법은 아주 많음.
    • 이때 누가 데이터를 부호화하고 복호화할까?
  • 데이터를 전달하는 가장 보편적인 방법을 살펴보자

 

 

🌀 2-1. 데이터베이스를 통한 데이터플로

하위 호환성 필요
  • 데이터베이스에 기록하는 프로세스는 데이터를 부호화
  • 데이터베이스에서 읽는 프로세스는 데이터를 복호화
    • 하위 호환성 필요

 

상위 호환성 필요
  • 동시에 다양한 프로세스가 데이터베이스를 접근
  • 데이터베이스 내 값이 새로운 버전의 코드로 기록된 다음, 
          현재 수행 중인 예전 버전의 코드로 그 값을 읽을 가능성이 있음.

 

문제 & 해결방안

 

  • 새로운 코드가 이전에는 없던 새 필드(photoURL)를 DB에 저장했다고 가정.
  • 이후 예전 코드가 이 데이터를 읽고 다시 기록하면? 새 필드 정보가 유실됨.
  • 해결하기 어려운 문제는 아니지만, 애플리케이션 설계 시 주의 필요.

 

 

다양한 시점에 기록된 다양한 값
  • 데이터가 코드보다 더 오래 산다(data outlives code)
  • 데이터를 새로운 스키마로 다시 기록(migration)하는 작업은 가능
  • 하지만 이 작업은 비싸기 때문에 가능하면 피하는게 좋음.

 

보관 저장소
  • snap-shot을 수시로 찍으면?
  • 데이터 dump는 보통 최신 스키마를 사용해 부호화

 

 

🌀 2-2 서비스를 통한 데이터플로 : REST와 RPC

클라이언트와 서버
  • 네트워크를 통해 통신해야 하는 프로세스가 있을 때 가장 일반적으로 배치(arrange)하는 방식
  • 서버는 API를 공개하고, 클라이언트는 API에 요청을 보내 서버와 상호작용을 함.
  • 이때 서비스가 공개한 API를 서비스라고 함.
  • 서버 자체가 다른 서비스의 클라이언트일 수 있음(ex. core - onchain 관계)
    • service-oriented architecture, SOA
    • microservices architecture, MSA 
  • 여러가지 측면에서 서비스는 데이터베이스와 비슷함 

 

웹 서비스
  • 서비스와 통신하기 위한 기본 프로토콜로 HTTP를 사용할 때 이를 웹 서비스라고 함
  • 대중적인 두 가지 방법 (REST, SOAP)

 

REST
  • HTTP의 원칙을 토대로한 설계 철학
  • REST 원칙에 따라 설계된 API를 RESTful이라고 함.

 

SOAP (Simple Object Access Protocol)
  • 네트워크 API 요청을 위함 XML 기반 프로토콜
  • 대부분의 HTTP 기능을 사용하지 않음.
  • 대신 WS라고 알려진 웹 서비스 프레임워크를 제공

 

웹 서비스의 많은 부분이 과장됐고, 여러 심각한 문제들
  • EJB, RMI는 자바로 제한
  • 분산 컴포넌트 객체 모델(Distributed Component Object Model)은 MSA 플랫폼으로 제한 
  • 공통 객체 요청 브로커(Common Object Request Broker)는 지나치게 복잡 & 호환성 zero

➔ 웹 서비스는 1970년대 부터 사용한 RPC의 아이디어를 기반으로 함

 

RPC 모델
  • 원격 네트워크 서비스 요청을 같은 프로세스 안에서,
          특정 프로그래밍 언어의 함수나 메서드를 호출하는 것과 동일하게 사용 가능하게 해줌.
    • 이러한 추상화를 위치 투명성(location tranparency)이라 고 함
  • 매우 편리한거 같지만, 접근 방식에 근본적인 문제가 있음.

 

로컬 함수 호출과 네트워크 요청은 다르다!
  • 로컬 함수 호출은 예측 가능함
  • 네트워크 요청은 예측이 어려움
    • 네크워크 문제로 요청과 응답이 유실 or 장비가 느려짐 or 무응답
    • 이러한 문제들은 제어할 수가 없음

 

네트워크로 인해 발생하는 문제에 대한 대응책이 필요하다!
  • 네트워크 타입 아웃이 나면 결과 없이 반환될 수 있음 
  • 응답만 유실 될 수 있음.
    • 프로토콜에서 중복 제거기법(멱등성, idempotence)을 적용해야 함.
  • 네트워크 요청은 함수 호출보다 훨씬 느리고 지연 시간을 예측할 수 없음.
  • 네트워크 요청의 경우, 오든 매개변수는 네크워크를 통해 전송될 수 있게끔 바이트열 인코딩이 필요
  • 모든 언어가 같은 타입을 가지는 것이 아니기 때문에 RPC를 사용할 때 신경써야 함.

 

RPC의 현재 방향
  • 그래도 RPC는 계속된다!
  • 요즘 RPC 프레임워크는 원격 요청이 로컬 함수 호출과 다르다는 사실을 노골적(explicit)으로 드러냄
    • 실패할지도 모를 비동기 작업을 캡슐화하기 위해 future(promise)를 사용함
    • gRPC는 하나의 요청과 하나의 응답뿐만 아니라
            시간에 따른 일련의 요청과 응답으로 구성된 스트림을 지원함
  • 근데 RESTful API가 가지는 다른 중요한 이점이 있음
    • 바로 디버깅에 적합하다는 점
    • 그리고 모든 주요 프로그래밍 언어와 플랫폼이 지원함(범용성 좋음)
  • 결과적으로
    • REST는 public API의 우세한(predominant) 스타일로 보이며
    • RPC의 주요 초점은 같은 데이터 센터 내의 같은 조직이 소유한 서비스간 요청에 있음

 

데이터 부호화와 RPC의 발전
  • 발전성이 있으려면 RPC 클라이언트와 서버를 독립적으로 변경하고 배포할 수 있어야 함.
  • 근데 RPC가 조직 경계를 넘나드는 통신에 사용될 때, 호환성 유지를 어렵게 함
    • 서비스 제공자는 클라이언트를 제어할 수 없음.
    • 따라서, 호환성을 깨는 변경이 필요하면 서비스 제공자는 보통 여러 버전의 서비스API를 유지해야 함.
  • RESTful API는 URL이나 HTTP Accept 헤더에 버전 번호를 사용하는 방식이 일반적

 

 

 

 

❐ 3. 메시지 전달 데이터플로


  • 지금까지는 두 개의 프로세스간 데이터 전달하는 다양한 방법을 살펴봄
  • 마지막 절에서는 RPC와 데이터베이스 간 비동기 메시지 전달 시스템을 살펴볼 거임

 

비동기 메시지 전달 시스템 (Asynchronous message-passing system)
  • 이 시스템은 클라이언트 요청을 낮은 지연 시간으로 다른 프로세스에 전달하는 점에서는 RPC와 비슷
  • 메시지를 직접 네트워크 연결로 전송하지 않고,
    • 임시로 메시지를 저장하는 message borker(또는 message queue)나
    • message-oriented middleware라는 중간 단계를 거쳐 전송한다는 점은 데이터베이스와 유사

 

메시지 브로커를 사용하는 방식의 장점 (비교군: RPC)
  • 시스템 안전성 향상
  • 메시지 유실 방지
  • 송신자가 수신자의 IP 주소나 포트 번호를 알 필요 없음.
  • 하나의 메시지를 여러 수신자로 전송할 수 있음.
  • 송신자는 누가 소비하는지 상관하지 않음.

 

메시지 브로커
  • 일반적으로 메시지 브로커는 다음과 같이 사용
    • 프로세스 하나가 메시지를 이름이 지정된 큐나 토픽으로 전송
    • 브로커는 해당 큐나 토픽 하나 이상의 소비자 또는 구독자에게 메시지를 전달
    • 동일한 토픽에 여러 생산자와 소비자가 있을 수 있음.
  • 보통 특정 데이터 모델을 강요하지 않음.
    • 메시지는 일부 메타데이터를 가진 바이트열이므로 모든 부호화 형식을 사용할 수 있음.
    • 부호화가 상위 호환성을 모두 가진다면
      • 게시자(publisher)와 소비자가 같은 시점에 동시에 배포될 필요가 없고,
      • 원하는 순서로 독립적으로 배포할 수 있음.

 

분산 액터 프레임워크
  • 액터 모델(actor model)
    • 단일 프로세스 안에서 동시성을 위한 프로그래밍 모델
    • 스레드(race condition, locking, deadlock과 연관된 문제들)를 직접 처리하는 대신
            로직이 액터에 캡슐화 됨.
    • 보통 각 액터는 하나의 클라이언트나 엔티티를 나타냄
    • 로컬 상태를 가질 수 있고 비동기 메시지의 송수신으로 다른 액터와 통신함
    • 메시지 전달을 보장하지 않음. (메시지 유실될 수도)
    • 각 액터 프로세스는 한 번에 하나의 메시지만 처리
      • 따라서, 스레드에 대해 걱정할 필요없고 각 액터는 프레임워크와 독립적으로 실행 가능
    • 여러 노드 간 애플리케이션 확장에 사용
      • 송/수신자의 노드 위치는 상관없이 동일한 메시지 전달 구조를 사용
      • 다른 노드에 있는 경우 메시지는 명백하게 바이트열로 부호화되고 네트워크를 통해 전송 & 복호화
    • 단일 프로세스 안에서도 메시지가 유실될 수 있다고 이미 가정함
      • 따라서 위치 투명성은 RPC 보다 액터 모델에서 더 잘 동작함
      • 네트워크를 통한 지연 시간이 동일한 프로세스 안에서 더 높을 순 있음.
        • 하지만 액터 모델을 사용한 경우 로컬과 원격 통신 간 근본적인 불일치가 적음
  • 인기 있는 분산 액터 프레임워크 세 가지 & 메시시 부호화 처리 방식
    1. 아카(Akka) - 자바의 내장 직렬화
    2. 올리언스(Orieans) - 기본적으로 사용자 정의 데이터 부호화 형식을 사용
    3. 얼랭(erlang)

 

 

 

 

 

❐ 4. 정리


  • 데이터 구조를 네트워크나 디스크 상의 바이트열로 변환하는 다양한 방법을 살펴봄.
  • 이런 부호화의 세부 사항은 효율성뿐만 아니라 애플리케이션의 아키텍쳐와 배포의 선택 사항에도 영향을 줌.
  • 순회식 업그레이드는 애플리케이션 변경을 쉽게 할 수 있는 발전성에 도움을 줌.
  • 시스템을 흐르는 모든 데이터는 상/하위 호환성을 제공하는 방식으로 부호화해야 함.

'Book > 데이터 중심 애플리케이션 설계' 카테고리의 다른 글

5장. 복제  (0) 2025.09.14
Part2. 분산 데이터  (0) 2025.09.13
3장. 저장소와 검색  (0) 2025.08.30
2장. 데이터 모델과 질의 언어  (0) 2025.08.23
1장. 신뢰할 수 있고 확장 가능하며 유지보수하기 쉬운 애플리케이션  (0) 2025.08.16
'Book/데이터 중심 애플리케이션 설계' 카테고리의 다른 글
  • 5장. 복제
  • Part2. 분산 데이터
  • 3장. 저장소와 검색
  • 2장. 데이터 모델과 질의 언어
gilbert9172
gilbert9172
gilbert9172 님의 블로그 입니다.
  • gilbert9172
    バックエンド
    gilbert9172
  • 전체
    오늘
    어제
    • All Categories (207)
      • 우테코 7기 (21)
        • 1주차 (8)
        • 2주차 (5)
        • 3주차 (6)
      • Langauge (6)
        • Java (3)
        • Kotlin (3)
      • Back-End (13)
        • SpringBoot (1)
        • Trouble Shooting (0)
        • Setup & Configuration (1)
        • SQL (3)
        • Redis (8)
      • Architecture (6)
        • Multi Module (1)
        • DDD (5)
      • CS (30)
        • Data Structure (6)
        • Operating System (0)
        • Network (12)
        • Database (10)
        • Design Pattern (2)
      • Algorithm (78)
        • 내용 정리 (18)
        • 문제풀이 (60)
      • DevOps (6)
        • AWS (5)
        • Git (1)
      • Front-End (1)
        • Trouble Shooting (1)
      • Project (6)
        • 페이스콕 (6)
      • Book (39)
        • 친절한 SQL 튜닝 (9)
        • 데이터 중심 애플리케이션 설계 (14)
        • 이벤트 기반 마이크로서비스 구축 (6)
        • Spring Batch docs (10)
        • Quartz docs (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    부분단조성
    오블완
    sliding-window
    Back-Tracking
    greedy
    binarysearch
    Two-Pointer
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
gilbert9172
4장. 부호화와 발전 (Encoding & Evolution)
상단으로

티스토리툴바