JSONB vs. BSON: PostgreSQL 및 MongoDB 와이어 프로토콜 추적
Source: Dev.to
개요
MongoDB의 BSON과 PostgreSQL의 JSONB 사이에는 본질적인 차이가 있습니다. 두 형식 모두 바이너리 JSON이지만 역할이 다릅니다. JSONB는 PostgreSQL 내부에서 JSON 데이터를 저장하기 위한 순수 저장 포맷이며, BSON은 MongoDB의 기본 데이터 형식으로, 애플리케이션 드라이버가 데이터베이스와 통신할 때 사용되고 디스크에 저장되는 형식이기도 합니다.
주요 차이점
- 목적
- JSONB – PostgreSQL 내부에서 저장 및 쿼리를 최적화하도록 설계되었습니다.
- BSON – 네트워크 전송 및 MongoDB 디스크 저장을 효율적으로 수행하도록 설계되었습니다.
- 데이터 타입
- JSONB는 JSON 타입(객체, 배열, 문자열, 숫자, 불리언, null)의 부분 집합만 지원합니다.
- BSON은
ObjectId,Date,Binary,Decimal128등 추가 타입을 제공합니다.
- 크기 오버헤드
- BSON은 타입 정보와 길이 접두사를 위해 추가 바이트를 포함하므로 동일한 데이터에 대해 JSONB보다 약간 더 큽니다.
- 인덱싱
- PostgreSQL은 GIN/GiST 인덱스를 사용해 JSONB 필드를 인덱싱할 수 있습니다.
- MongoDB는 BSON 필드에 직접 인덱스를 제공합니다.
PostgreSQL 와이어 프로토콜 추적
PostgreSQL은 자체 와이어 프로토콜을 사용해 클라이언트와 통신합니다. 원시 메시지를 확인하려면:
# Using pg_recvlogical to capture logical replication messages
pg_recvlogical \
--dbname=postgres \
--slot=debug_slot \
--start \
--verbose
또는 tcpdump를 사용합니다:
sudo tcpdump -i any -w pg.pcap port 5432
그런 다음 캡처 파일을 Wireshark에서 열고 필터 postgresql을 적용하면 프로토콜 메시지를 디코딩할 수 있습니다.
MongoDB 와이어 프로토콜 추적
MongoDB는 BSON 와이어 프로토콜을 사용합니다. 트래픽을 캡처하는 간단한 방법은 mongodump와 tcpdump를 함께 사용하는 것입니다:
# Capture traffic on default MongoDB port 27017
sudo tcpdump -i any -w mongo.pcap port 27017
Wireshark에서 필터 mongodb를 사용해 메시지를 디코딩합니다. OP_QUERY, OP_INSERT와 같은 연산과 해당 BSON 페이로드를 확인할 수 있습니다.
예시: BSON 문서 디코딩
다음과 같은 원시 바이트(헥스)를 캡처했다고 가정합니다:
16 00 00 00 02 66 6f 6f 00 04 00 00 00 62 61 72 00 00
해석:
| 오프셋 | 바이트 | 의미 |
|---|---|---|
| 0‑3 | 16 00 00 00 | 문서 길이 (22 바이트) |
| 4 | 02 | 타입: 문자열 |
| 5‑7 | 66 6f 6f | 키: foo |
| 8 | 00 | 키의 널 종료자 |
| 9‑12 | 04 00 00 00 | 문자열 길이 (4) |
| 13‑15 | 62 61 72 | 값: bar |
| 16 | 00 | 값의 널 종료자 |
| 17‑21 | 00 00 00 00 | 문서 종료 마커 |
언제 어떤 포맷을 사용할까
- JSONB 사용: PostgreSQL 내부에서 작업하고 강력한 SQL 쿼리 기능, 인덱싱, 트랜잭션 보장이 필요할 때.
- BSON 사용: MongoDB와 상호 작용할 때, 특히 MongoDB 고유 데이터 타입이 필요하거나 유연한 스키마와 샤딩 기능을 활용하고 싶을 때.
와이어 프로토콜과 그 기반이 되는 바이너리 포맷을 이해하면 성능 문제 디버깅, 커스텀 드라이버 개발, 혹은 데이터베이스가 내부적으로 어떻게 동작하는지에 대한 깊은 통찰을 얻는 데 도움이 됩니다.