데이터 직렬화 포맷 비교: JSON, Protobuf, MessagePack
직렬화는 데이터 구조를 저장하거나 전송할 수 있는 포맷으로 변환하고 나중에 재구성하는 것입니다. 포맷의 선택은 성능, 페이로드 크기, 상호 운용성, 개발자 경험에 영향을 미칩니다. 이 가이드에서는 가장 인기 있는 옵션을 비교합니다.
포맷 개요
| 포맷 | 유형 | 스키마 | 사람이 읽을 수 있음 | 바이너리 |
|---|---|---|---|---|
| JSON | 텍스트 | 선택 (JSON Schema) | 예 | 아니오 |
| Protocol Buffers | 바이너리 | 필수 (.proto) | 아니오 | 예 |
| MessagePack | 바이너리 | 없음 | 아니오 | 예 |
| CBOR | 바이너리 | 선택 (CDDL) | 아니오 | 예 |
| Avro | 바이너리 | 필수 (JSON 스키마) | 아니오 | 예 |
| YAML | 텍스트 | 선택 | 예 | 아니오 |
| XML | 텍스트 | 선택 (XSD) | 예 | 아니오 |
JSON: 보편적 기본값
JSON은 브라우저에서 네이티브로 지원되고 사실상 모든 프로그래밍 언어에서 지원되는 가장 널리 사용되는 직렬화 포맷입니다.
{
"name": "Alice",
"age": 30,
"roles": ["admin", "editor"],
"active": true
}
강점: 보편적 지원, 사람이 읽을 수 있음, 스키마 불필요, 우수한 디버깅. 약점: 장황함, 바이너리 데이터 미지원, 스키마 강제 없음, 바이너리 포맷보다 느린 파싱. 크기: 이 예시 = 74 바이트.
JSON 포맷터로 JSON을 포맷하세요.
Protocol Buffers (Protobuf)
Google의 바이너리 직렬화 포맷. 스키마 정의가 필요합니다:
message User {
string name = 1;
int32 age = 2;
repeated string roles = 3;
bool active = 4;
}
강점: 매우 컴팩트, 매우 빠름, 스키마를 통한 강한 타이핑, 전후방 호환, 코드 생성. 약점: 사람이 읽을 수 없음, 스키마 정의 필요, 코드 생성 단계 필요, 디버깅이 더 어려움. 크기: 동일 데이터 ≈ 28 바이트 (JSON보다 62% 작음).
MessagePack
구조적으로 JSON과 동등한 바이너리 포맷 — 같은 타입, 스키마 불필요:
const msgpack = require('msgpack-lite');
const packed = msgpack.encode({name: "Alice", age: 30, roles: ["admin", "editor"], active: true});
// 결과: 약 45바이트 Buffer
강점: JSON의 드롭인 대체 (같은 데이터 모델), JSON보다 작음, 빠른 파싱, 스키마 불필요. 약점: 사람이 읽을 수 없음, Protobuf보다 덜 컴팩트, 스키마 유효성 검사 없음. 크기: 동일 데이터 ≈ 45 바이트 (JSON보다 39% 작음).
CBOR (Concise Binary Object Representation)
바이너리 데이터를 위한 IETF 표준 (RFC 8949). MessagePack과 유사한 목표에 추가 기능:
강점: IETF 표준, 확장 타입(날짜, BigInt)을 위한 태그 지원, 결정론적 인코딩, 제한된 장치(IoT)에 적합. 약점: MessagePack보다 작은 생태계, 사람이 읽을 수 없음. 크기: MessagePack과 유사.
Apache Avro
빅데이터 생태계에서 많이 사용 (Hadoop, Kafka):
강점: 스키마 진화 (필드 안전하게 추가/제거), 컴팩트 인코딩, 내장 압축, 스트리밍 데이터에 적합. 약점: 읽기와 쓰기 모두에 스키마 필요, 요청-응답 API에 덜 적합. 크기: 스키마를 별도로 공유하면 매우 컴팩트.
성능 비교
벤치마크는 구현에 따라 다르지만, 일반적인 상대 성능:
| 포맷 | 직렬화 속도 | 역직렬화 속도 | 크기 |
|---|---|---|---|
| JSON | 1x (기준) | 1x (기준) | 1x (기준) |
| MessagePack | 2-4배 빠름 | 2-4배 빠름 | 0.6x |
| Protobuf | 3-10배 빠름 | 3-10배 빠름 | 0.3-0.5x |
| Avro | 2-5배 빠름 | 2-5배 빠름 | 0.3-0.5x |
| CBOR | 2-4배 빠름 | 2-4배 빠름 | 0.6x |
실제 수치는 데이터 구조, 언어 구현, 스키마 컴파일 분산 여부에 크게 의존합니다.
적합한 포맷 선택
JSON을 사용할 때:
- 웹 API 구축 (브라우저 지원이 네이티브)
- 사람이 읽을 수 있는 것이 중요 (설정 파일, 디버깅)
- 상호 운용성이 우선 (모든 언어가 JSON 지원)
- 스키마 유연성이 필요 (다양한 문서 구조)
Protobuf를 사용할 때:
- 성능이 중요 (고처리량 서비스)
- 엄격한 타이핑이 필요 (강제 스키마)
- 생산자와 소비자 모두를 제어할 수 있을 때
- 서비스 통신에 gRPC 사용
MessagePack를 사용할 때:
- 스키마 오버헤드 없이 더 작은 페이로드를 원할 때
- JSON의 드롭인 대체가 필요
- 좋은 MessagePack 지원이 있는 언어로 작업할 때
- Redis나 다른 시스템이 MessagePack를 네이티브로 사용할 때
Avro를 사용할 때:
- 빅데이터 파이프라인 작업 (Kafka, Hadoop)
- 스키마 진화가 중요할 때
- 데이터를 장기 저장할 때 (스키마 레지스트리가 미래 독자를 도움)
텍스트 포맷 간 변환은 JSON to YAML 변환기가 가장 일반적인 변환 요구를 처리합니다.
자주 묻는 질문
웹 브라우저에서 바이너리 포맷을 사용할 수 있나요?
네, 하지만 주의사항이 있습니다. MessagePack과 CBOR에는 브라우저에서 작동하는 JavaScript 라이브러리가 있습니다. Protobuf는 protobufjs 라이브러리가 필요합니다. 하지만 JSON은 네이티브 브라우저 지원이 있고, fetch와 함께 작동하며, 브라우저 DevTools에서 디버깅이 가능하기 때문에 웹 API의 기본값으로 유지됩니다.
JSON에서 Protobuf로 API를 전환해야 하나요?
JSON 직렬화로 인한 성능 병목이 측정된 경우에만 그렇습니다. 대부분의 웹 애플리케이션에서 JSON은 충분히 빠르며, 개발자 경험의 이점 (가독성, 디버깅, 도구)이 바이너리 포맷의 성능 이점보다 큽니다. Protobuf는 일반적인 웹 API가 아닌 고처리량 마이크로서비스 통신에서 빛을 발합니다.
관련 리소스
- JSON 포맷터 — JSON 포맷 및 유효성 검사
- YAML vs JSON — 텍스트 기반 포맷 비교
- CSV vs JSON vs XML — 데이터 교환 포맷 선택