# 직렬화(Serialization) 및 역직렬화(Deserialization)
직렬화(Serialization)와 역직렬화(Deserialization)는 컴퓨팅 시스템에서 데이터 구조나 객체를 연속적인 바이트 스트림으로 변환하고, 이 스트림으로부터 다시 원래의 데이터 구조를 복원하는 과정을 말한다. 이 두 과정은 분산 시스템, 파일 저장, 네트워크 통신, 캐싱, RPC 등 다양한 영역에서 핵심 기술로 활용된다. 영어 용어인 serialization/deserialization, marshalling/unmarshalling 등의 동의어가 널리 사용되기도 한다.
---
## 1. 개요와 정의
- 직렬화(Serialization)
- 목적: 메모리 상의 데이터 구조를 바이트 시퀀스로 변환하여 저장, 전송, 재생성 가능하도록 한다.
- 특징: 포맷과 엔디안, 타임스탬프 표현 방식, 문자열 인코딩 등을 결정한다.
- 역직렬화(Deserialization)
- 목적: 저장되거나 전송된 바이트 스트림을 다시 원래의 데이터 구조나 객체로 복원한다.
- 주의점: 잘못된 데이터 형식이나 악의적 데이터로부터 시스템을 보호하기 위한 검증이 필수적이다.
두 과정은 서로 반대 방향의 연산이지만, 구현과 보안 측면에서 함께 다루어져야 한다. 예를 들어, 역직렬화 동안 입력 데이터의 유효성 검사와 스키마 검증이 확보되지 않으면 원격 코드 실행 등 보안 취약점이 발생할 수 있다.
- 데이터 흐름 예시
- 객체 그래프 → 직렬화 → 네트워크/저장 → 역직렬화 → 객체 그래프
- 데이터 표현 예시
- 텍스트 포맷: JSON, YAML, XML
- 이진 포맷: Protocol Buffers, MessagePack, CBOR, Avro, Thrift, FlatBuffers
수식 예시
- 직렬화 오버헤드 비율의 표현: $OverheadRate = \\frac{SerializedSize - OriginalSize}{OriginalSize}$
- 데이터 크기의 근사 관계: $SerializedSize \\approx OriginalSize + Overhead$
---
## 2. 용어 및 개념 정리
- 데이터 구조(Data Structure): 객체(Object), 엔티티(Entity), 필드(Field)로 구성된 구성 요소.
- 스키마(Schema): 데이터의 구조, 필드의 타입, 필수 여부 등을 정의하는 형식 정의.
- 시리얼라이즈링/마샬링(Marshalling)과 언마샬링(Unmarshalling)
- 시리얼라이즈링/마샬링: 객체를 바이트 스트림으로 변환하는 과정.
- 언마샬링/디시리얼라이즈링: 바이트 스트림을 객체로 복원하는 과정.
- 포맷(Formant): 데이터의 인코딩 규칙과 구조를 나타내는 표준화된 형식.
- 스키마 진화(Schema Evolution): 데이터 포맷의 버전이 바뀌어도 기존 데이터와의 호환성을 유지하는 방법.
---
## 3. 직렬화 포맷의 유형
직렬화 포맷은 용도에 따라 텍스트 기반과 이진 기반으로 나눌 수 있으며, 각 포맷은 특정 요구사항에 맞춘 장단점을 가진다.
- 텍스트 기반 포맷
- JSON: 가독성 높음, 대부분의 언어에서 기본적인 지원. 느슨한 타입 매핑 가능.
- YAML: 사람 친화적이지만 중첩 구조에서 파서가 복잡해질 수 있음.
- XML: 확장성 있는 태그 기반 표현, 메타데이터와 스키마 정의에 강점.
- 이진 포맷
- Protocol Buffers (Protobuf): 정형화된 스키마 기반으로 빠른 직렬화/역직렬화 및 작은 크기, 강한 타입 검사.
- MessagePack: 바이너리 JSON으로 간주되며 가볍고 빠른 처리.
- CBOR: JSON의 이진 표현으로 확장성과 효율성의 균형.
- Avro: 스키마 진화와 메시지 방향의 데이터 교환에 강점.
- Thrift: 인터페이스 정의 언어와 런타임 지원으로 다중 언어 간의 RPC에 적합.
- FlatBuffers, Cap'n Proto: 제로-복사(zero-copy) 접근으로 로딩 시 비용 최소화.
- 특수 목적 포맷
- ORMs/DB용 포맷, 이벤트 소싱용 로그 포맷 등 특정 도메인에 특화된 포맷들이 존재.
각 포맷은 다음과 같은 속성으로 비교된다.
- 스키마 필요 여부
- 인간 가독성
- 타입 안정성
- 확장성(스키마 진화)
- 연산 성능(직렬화/역직렬화 속도, 메모리 사용)
- 크기 효율성
- 보안 및 검증 지원
---
## 4. 비교 기준과 선택 가이드
- 인간 가독성과 생산성
- 텍스트 포맷(JSON, YAML, XML)은 디버깅과 수동 수정이 쉽다.
- 데이터 사이즈와 네트워크 대역폭
- 이진 포맷은 일반적으로 더 작은 크기와 빠른 직렬화/역직렬화를 제공한다.
- 스키마 관리와 호환성
- 스키마 기반 포맷(Protobuf, Avro, Thrift)은 버전 관리와 역호환성에 강점이 있다.
- 실시간성과 메모리 사용
- 제로-복사나 스트리밍 친화적인 포맷은 대용량 이벤트 스트림이나 실시간 시스템에 적합하다.
- 보안 고려사항
- 역직렬화 취약점에 대비해 데이터 검증, 화이트리스트 타입 허용, 서명/암호화 등을 고려해야 한다.
---
## 5. 스키마, 검증 및 호환성
- 스키마 기반 직렬화의 장점
- 강력한 타입 검사, 자동 코드 생성, 버전 관리의 용이성.
- 스키마 진화의 원칙
- 역방향 호환성(Backward compatibility): 구버전이 신버전 포맷을 읽을 수 있어야 함.
- 앞으로의 확장성(Forward compatibility): 신버전이 구버전을 읽을 수 있어야 함.
- 데이터 검증의 중요성
- 역직렬화 시점에 데이터의 타입, 범위, 필수 여부, 불필요한 필드 여부를 검사해야 한다.
- 자주 발생하는 스키마 문제
- 필수 필드의 누락, 부적절한 타입 매핑, 필드 이름의 충돌, 스키마 버전 관리의 혼란
---
## 6. 보안 고려사항
- Deserialization Attack
- 악의적 데이터로 인해 원격 코드 실행, 서비스 거부, 데이터 손상 등이 발생할 수 있다.
- 방지책
- 입력 검증: 허용된 타입만 처리하도록 화이트리스트 구성.
- 서명 및 암호화: 데이터 무결성과 기밀성 보장.
- 스키마 검증: 스키마 버전 체크 및 미지원 필드 무시 정책.
- 안전한 기본값 사용: 미리 정의된 기본값으로 누락 필드 처리.
- 라이브러리 업그레이드 및 취약점 관리.
---
## 7. 구현 가이드라인
- API 설계
- 명확한 직렬화/역직렬화 경계, 예외 처리, 타임스탬프 포맷 일관성.
- 스키마 버전 관리
- 버전 태깅, 기본값, 디폴트 동작 정의로 호환성 유지.
- 타입 매핑
- 언어 간의 기본 타입 매핑 정의, 日期/시간/바이너리 데이터의 표현 규칙 명시.
- 보안 설계
- 입력 유효성 검사, 서명/암호화, 신뢰할 수 있는 소스만 역직렬화 허용.
- 오류 처리
- 역직렬화 실패 시의 안전한 실패 처리 및 로깅 정책 수립.
---
## 8. 예제
- 텍스트 포맷 예시: JSON
- 원본 데이터
- 예: 사람(Person) 객체: { "name": "홍길동", "age": 25, "emails": ["
[email protected]"] }
- 직렬화 예시(JSON)
- ```json
{
"name": "홍길동",
"age": 25,
"emails": ["
[email protected]"]
}
```
- 역직렬화 예시
- ```json
const obj = JSON.parse('{"name":"홍길동","age":25,"emails":["
[email protected]"]}');
```
- 이진 포맷 예시: Protocol Buffers의 간략한 정의
- proto 파일
- ```proto
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
repeated string emails = 3;
}
```
- 직렬화/역직렬화의 일반적 사용 흐름
- 1) 메시지 인스턴스 생성
- 2) SerializeToString() 호출로 이진 데이터 생성
- 3) ParseFromString()으로 복원
- 간단한 워크플로우 요약
- 데이터 모델링 → 스키마 정의 → 직렬화 포맷 선택 → 구현 및 검증 → 모니터링 및 보안 강화
---
## 9. 데이터 직렬화의 생태계와 실무 트렌드
- 마이크로서비스 아키텍처에서의 데이터 교환 포맷 표준화
- 이벤트 소싱, CQRS 등 아키텍처에 따른 포맷 선택의 차이
- 스키마 진화 전략의 중요성: 롤링 업데이트 중 호환성 유지의 필요성
- 보안 중심의 역직렬화 방어 설계의 보편화
---
## 10. 요약 및 결론
직렬화와 역직렬화는 데이터의 저장, 전송, 재구성에 필수적인 기술로, 선택한 포맷의 특성에 따라 성능, 용이성, 보안성이 달라진다. 텍스트 기반 포맷은 가독성과 개발 편의성을 제공하는 반면, 이진 포맷은 속도와 공간 효율성을 크게 개선한다. 스키마 관리와 보안 고려가 동반될 때 시스템의 견고성과 확장성이 크게 향상된다.
---
관련 문서: [[Serialization Fundamentals]], [[Deserialization Security]], [[Binary Encoding Formats]], [[Schema Evolution and Compatibility]]