· 5분 읽기
MongoDB 아키텍처: WiredTiger 엔진과 샤딩 설계
MongoDB의 성능 문제는 두 층위에서 발생합니다. 단일 노드 안에서는 WiredTiger 스토리지 엔진의 캐시와 체크포인트가 병목을 만들고, 노드 하나로 감당할 수 없는 규모가 되면 샤딩이라는 구조적 선택이 필요해집니다. 이 글에서는 WiredTiger의 내부 동작으로 단일 노드 병목의 원인을 먼저 이해하고, 그 한계를 넘기 위한 샤딩 설계를 이어서 다룹니다.
WiredTiger: 단일 노드의 내부 동작
WiredTiger를 이해할 때 중요한 것은 구현 디테일보다 "병목이 어디서 생기는가"입니다. 쓰기의 핵심 동작은 세 단계입니다.
- WAL(저널)에 기록
- 메모리 캐시에 반영
- 체크포인트 시 디스크에 반영
이 순서 덕분에 장애 복구와 성능을 함께 잡을 수 있습니다. 이제 운영에서 반드시 알아야 할 네 가지를 살펴봅니다.
문서 수준 동시성과 MVCC
WiredTiger는 문서 수준 동시성 제어와 MVCC를 제공합니다. 읽기와 쓰기가 서로 덜 막히므로 읽기·쓰기가 섞인 혼합 워크로드에서 유리합니다.
캐시와 eviction 튜닝
캐시가 작으면 eviction 압력이 커지고 지연이 튑니다. 반대로 캐시를 키우면 시스템 전체에 메모리 압박이 옵니다. 정답 값은 없으며, 지표를 관측한 뒤 조정하는 것이 필수입니다.
내구성과 TPS의 트레이드오프
체크포인트와 저널의 내구성 설정을 낮추면 TPS를 올릴 수 있지만, 장애 시 손실 범위가 함께 늘어납니다. 성능 수치가 아니라 서비스 SLO를 기준으로 결정해야 합니다.
압축
압축은 저장공간과 CPU의 트레이드오프입니다. 일반적으로 기본 압축에서 시작해, I/O 병목이 심할 때만 재평가하는 것이 안전합니다.
정리하면, WiredTiger 튜닝은 단일 옵션 최적화가 아니라 캐시, 체크포인트, 저널 정책을 함께 맞추는 작업입니다.
단일 노드의 한계, 그리고 샤딩
튜닝으로도 해결되지 않는 시점이 옵니다. 샤딩이 필요한 신호는 다음과 같습니다.
- 단일 노드 디스크/메모리 한계에 근접
- 쓰기 처리량이 수직 확장으로 감당되지 않음
- 특정 컬렉션이 지속적으로 핫스팟을 유발
샤딩은 "빨라지는 기능"이 아니라 "용량과 처리량 한계를 넘기기 위한 구조"입니다.
클러스터 구성 요소
mongos: 라우터. 클라이언트 요청을 적절한 샤드로 전달합니다.shard replica set: 실제 데이터를 저장합니다.config server replica set: chunk와 메타데이터를 저장합니다.
샤드 키 선택
샤딩의 성패는 여기서 갈립니다. 좋은 샤드 키는 세 조건을 동시에 만족해야 합니다.
- 높은 카디널리티
- 균등 분산
- 실제 쿼리 패턴과의 정합성
전략 비교
| 전략 | 장점 | 단점 | 적합한 케이스 |
|---|---|---|---|
| Hashed | 분산이 균등함 | 범위 조회 비효율 | 랜덤 조회 중심 |
| Ranged | 범위 조회 효율 | 시간축 핫스팟 위험 | 시계열/정렬 조회 |
| Compound | 유연한 분산 설계 | 설계/운영 복잡도 증가 | 복합 조건 조회 |
최소 구성 절차
// 1) 샤딩 활성화
sh.enableSharding("mydb")
// 2) 컬렉션 샤딩
sh.shardCollection("mydb.orders", { customerId: "hashed" })
Targeted vs Scatter-Gather
- Targeted Query: 쿼리에 샤드 키가 포함되어 특정 샤드만 조회합니다.
- Scatter-Gather: 샤드 키가 없어 모든 샤드를 조회합니다.
두 방식의 운영 비용 차이가 크므로, 주요 API는 샤드 키를 쿼리에 포함하도록 계약을 잡아야 합니다.
운영 중 자주 터지는 문제
- 단조 증가 키(
createdAt단일 키)로 특정 샤드에 쓰기가 집중되는 핫스팟 - chunk 분할/이동이 피크 시간과 겹쳐 지연 급증
- 샤드 키 변경 불가 제약을 늦게 인지해 마이그레이션 비용 폭발
특히 샤드 키는 한 번 정하면 변경할 수 없으므로, 후보 키를 실제 트래픽으로 검증한 뒤 결정해야 합니다.
종합 운영 체크리스트
단일 노드(WiredTiger) 관점입니다.
serverStatus().wiredTiger지표를 정기 수집합니다.- eviction 지표와 write latency를 함께 관찰합니다.
- checkpoint 스파이크 시간대를 파악합니다.
- 대량 배치 작업은 평시 트래픽과 분리합니다.
클러스터(샤딩) 관점입니다.
sh.status()와getShardDistribution()을 정기 확인합니다.- 밸런서 작업 시간대를 트래픽 저점으로 제한합니다.
- 샤드 키 후보는 실제 트래픽으로 리허설한 뒤 결정합니다.
- 다중 샤드 트랜잭션 사용 비율을 모니터링합니다.
정리
- 단일 노드 성능은 WiredTiger의 WAL → 캐시 → 체크포인트 흐름에서 결정되며, 튜닝은 캐시·체크포인트·저널 정책을 함께 맞추는 작업입니다.
- 내구성 설정과 압축은 모두 트레이드오프이므로 서비스 SLO를 기준으로 판단합니다.
- 샤딩은 성능 개선 기능이 아니라 용량과 처리량 한계를 넘기 위한 구조이며, 성공 여부는 기술 스택이 아니라 샤드 키에서 결정됩니다.
- 카디널리티, 균등 분산, 쿼리 정합성 세 조건을 초기 설계에서 함께 검증해야 장기 운영 비용을 줄일 수 있습니다.