샤딩(Sharding)은 하나의 데이터베이스를 여러 서버(샤드)에 수평 분할하여 저장하는 확장 전략이다. 단순 파티셔닝과 달리 각 샤드는 독립적인 서버로, 쓰기와 읽기 모두 분산된다.
샤딩 전략 유형
1. Range-based Sharding (범위 기반)
user_id 1-100만 → Shard 1
user_id 100만-200만 → Shard 2
user_id 200만-300만 → Shard 3
장점: 범위 쿼리 효율적
단점: 핫스팟 가능 (최신 데이터에 집중)
2. Hash-based Sharding (해시 기반)
shard = hash(user_id) % num_shards
user_id 1001 → hash(1001) % 4 = 2 → Shard 2
user_id 1002 → hash(1002) % 4 = 3 → Shard 3
장점: 균등 분포
단점: 샤드 추가 시 데이터 이동 필요 → 일관 해싱으로 해결
3. Directory-based Sharding (디렉토리 기반)
조회 서비스 → [샤드 매핑 테이블] → 해당 샤드
user_id → 샤드 매핑은 DB에 저장
장점: 유연한 매핑 변경 가능
단점: 조회 서비스가 병목/단일 장애점
핫스팟 문제와 해결
python
# 핫스팟 예시: 인기 유튜버는 항상 같은 샤드
shard = hash(creator_id) % 10
# 1억 구독자 채널 → 항상 Shard 3에 부하 집중
# 해결 1: 가상 샤드 (Virtual Shards)
VIRTUAL_SHARDS = 1000
virtual_shard = hash(creator_id) % VIRTUAL_SHARDS
real_shard = virtual_shard % REAL_SHARDS
# 가상 샤드를 물리 샤드에 동적 재배치 가능
# 해결 2: 복합 키에 랜덤성 추가
shard_key = f"{creator_id}_{random.randint(0, 9)}" # suffix 분산
Cross-shard 문제
sql
-- 단일 샤드 쿼리 (효율적)
SELECT * FROM orders WHERE user_id = 1001; -- Shard 2만 조회
-- Cross-shard 쿼리 (비효율적)
SELECT * FROM orders WHERE amount > 10000; -- 모든 샤드 조회 필요
SELECT COUNT(*) FROM users; -- 모든 샤드 집계 후 합산
샤딩 vs 레플리케이션
| 항목 | 샤딩 | 레플리케이션 |
|---|
| 목적 | 쓰기 확장 | 읽기 확장 + 가용성 |
| 데이터 | 분산 (각 샤드 일부) | 복제 (모든 노드 동일) |
| 복잡도 | 높음 | 낮음 |
| 조인 | 어려움 | 쉬움 |
관련 개념