DB 엔지니어링 — 샤딩·Consistent Hashing

2026-05-03확률과 통계 마스터 노트

데이터베이스 엔지니어링 마스터 노트 시리즈 4편. 단일 DB 한계와 샤딩의 등장, 파티셔닝 vs 샤딩의 결정적 차이, Range·Hash·Geographic 샤딩 3전략, Consistent Hashing이 노드 추가에서 빛나는 이유, Cross-Shard JOIN 함정, Resharding의 어려움, 언제 샤딩해야 하는가까지.

이 글은 데이터베이스 엔지니어링 마스터 노트 시리즈의 네 번째 편입니다. 3편(파티셔닝)이 단일 DB 안 분할이었다면, 이번엔 여러 서버로 분산 — 샤딩.

수억·수십억 사용자 = 단일 DB 한계 도달. 샤딩 = 마지막 수평 확장 카드. 다만 샤딩은 비싼 결정 — 잘못 선택하면 운영 지옥. 언제·어떻게가 핵심.

샤딩이란?

데이터를 여러 DB 인스턴스(샤드)에 분산.

거대한 users 테이블 (10억 행, 단일 DB)
   ↓ 샤딩
shard1 (1~10억): users (1~3억)
shard2 (2~10억): users (3억~6억)
shard3 (3~10억): users (6억~10억)

각 샤드 = 별도 DB 서버

각 샤드는 자체 PostgreSQL·MySQL 같은 완전한 DB. 애플리케이션이 어느 샤드에 갈지 결정.

전통 DB의 한계

단일 노드 한계

CPU      = 32~96 코어 한계
RAM      = 1~6TB 한계
Storage  = 수십 TB 한계
연결     = 수만 동시 연결 한계
처리량   = 수만 QPS 한계

이 한계 도달 = 수직 확장(더 큰 서버) 비용 폭발.

샤딩의 등장

샤드 1 → 32 코어 / 256GB RAM
샤드 2 → 32 코어 / 256GB RAM
샤드 3 → 32 코어 / 256GB RAM
샤드 4 → 32 코어 / 256GB RAM

= 합계 128 코어 / 1TB RAM

수평 확장 = 이론상 무제한.

파티셔닝 vs 샤딩 — 결정적 차이

구분 Partitioning Sharding
범위 단일 DB 안 여러 DB 서버
투명성 DBMS 자동 처리 애플리케이션 라우팅
관리 단일 DB 관리 분산 관리
Join 모든 파티션 가능 Cross-Shard JOIN 어려움
트랜잭션 보통 ACID 분산 트랜잭션 복잡
적합 단일 노드 한계 내 단일 노드 초과

여기서 정말 중요한 시험 함정 — 샤딩은 ACID 보장 어려움. Cross-Shard 트랜잭션은 2PC(Two-Phase Commit) 필요. 성능 큰 비용. 8편(고급)에서 자세히.

샤딩 전략 3가지

1. Range Sharding

shard1: user_id 1~1000만
shard2: user_id 1000만~2000만
shard3: user_id 2000만~3000만

장점 — 범위 쿼리 한 샤드만.

단점 — Hot Spot 위험. 신규 사용자가 shard3에 몰림.

2. Hash Sharding

shard_id = hash(user_id) % N

장점 — 균등 분산, hot spot 회피.

단점 — 범위 쿼리 모든 샤드 스캔 필요.

여기서 정말 중요한 시험 함정 — 단순 modulo 해시는 Resharding 지옥. 노드 1개 추가 시 거의 모든 데이터 재배치 필요. 해결 = Consistent Hashing.

3. Geographic / Directory Sharding

shard_kr: 한국 사용자
shard_us: 미국 사용자
shard_eu: 유럽 사용자

또는 Directory Service 사용 — 별도 매핑 테이블에 "user_id → shard_id" 저장.

장점 — 유연. 단점 — Directory가 SPOF·병목.

Consistent Hashing — 노드 변경에 강건

단순 해시의 문제

N=4 샤드
key=100 → 100 % 4 = shard 0

N=5 샤드 추가
key=100 → 100 % 5 = shard 0

N=6
key=100 → 100 % 6 = shard 4 (위치 변경!)

거의 모든 키가 새 위치 → 대량 데이터 이동.

Consistent Hashing 동작

Hash 공간 (0 ~ 2^32) — 원형(ring)으로 배치

Ring:
  shard1 ─→ shard2 ─→ shard3 ─→ shard4 ─→ (다시 shard1)

키:
  hash(key) → ring의 한 위치 → 시계방향 가장 가까운 shard에 저장

노드 추가/제거 시 인접 영역만 영향 — 1/N 데이터만 이동.

shard5 추가:
  shard1과 shard2 사이에 위치
  → shard2의 일부 데이터만 shard5로 이동
  → shard1·shard3·shard4의 데이터는 그대로

여기서 정말 중요한 시험 함정 — Consistent Hashing은 Cassandra·DynamoDB·MongoDB·Redis Cluster 등 거의 모든 분산 DB의 표준입니다.

Virtual Nodes (vnodes)

각 물리 샤드에 가상 노드 여러 개 매핑 → ring에 더 균등 분산.

shard1 → vnode1, vnode10, vnode30 (가상 위치 3개)
shard2 → vnode5, vnode20, vnode40

분산 균등성 ↑.

샤딩의 단점

1. Cross-Shard JOIN

-- 단일 DB
SELECT u.name, o.amount
FROM users u JOIN orders o ON u.id = o.user_id;

-- 샤딩 환경
-- users는 shard1, orders는 shard5에 있다면?
-- 애플리케이션이 두 샤드 조회 후 코드로 JOIN

해결법:

  • 데이터 재구조화 — 같은 샤드에 관련 데이터 (user_id로 모든 관련 데이터 샤딩)
  • 애플리케이션 레벨 JOIN — 두 쿼리 후 코드 결합
  • 데이터 중복 (denormalization)

2. 분산 트랜잭션

shard1: account A 출금
shard2: account B 입금

ACID 보장 = 2PC (Two-Phase Commit)
  Phase 1: 모든 샤드 PREPARE
  Phase 2: 모든 PREPARE 성공 → COMMIT, 하나라도 실패 → ROLLBACK

여기서 시험 함정이 하나 있어요. 2PC는 느리고 장애에 약함 (coordinator 다운 = 정지). 가능하면 분산 트랜잭션 회피 — Saga 패턴 등 대안.

3. Resharding

샤드 수 변경 = 데이터 재분배. 운영 중 매우 어려움.

4 → 8 샤드 확장
- 데이터 이동 시간 (수일~수주)
- 운영 중 일관성 유지
- 다운타임 최소화

도구 — Vitess (MySQL), Citus (PostgreSQL), MongoDB Sharding.

4. 운영 복잡도

  • 모니터링 N배
  • 백업 N개 동기화
  • 보안 패치 N대
  • 모든 샤드의 일관된 스키마 변경

언제 샤딩해야 하는가?

샤딩 전 시도할 것:

1. 인덱스 최적화 (2편)
2. Read Replica (5편)
3. 캐시 (Redis·Memcached)
4. 파티셔닝 (3편)
5. Vertical Scaling (큰 서버)
   ↓
   ↓ 모두 부족하면
   ↓
6. 샤딩 (마지막 수단)

여기서 정말 중요한 시험 함정 — 샤딩은 마지막 수단. 단일 큰 서버(64코어·1TB RAM)로 수년 동안 충분한 경우 많음. 너무 일찍 샤딩 = 비용 큼.

신호:

  • 단일 서버 RAM/Disk 한계
  • 단일 서버 처리량 한계 (수만 QPS+)
  • 지리적 분산 필요 (글로벌 서비스)
  • 강제 샤딩 정책 (compliance·격리)

샤딩 키 선정

핵심 결정 — 어떤 컬럼으로 샤딩할 것인가.

좋은 샤딩 키:

  • 카디널리티 높음 — 균등 분산
  • 자주 WHERE에 등장 — 단일 샤드 조회
  • 변경 안 됨 — 샤드 이동 비용 큼
  • JOIN 효율 — 관련 데이터 같은 샤드

예시:

  • 멀티 테넌트 SaaS — tenant_id
  • 소셜 — user_id
  • 게임 — account_id 또는 region

여기서 시험 함정이 하나 있어요. 잘못된 샤딩 키는 거의 되돌릴 수 없음. 신중히 선정. 가능하면 데이터 모델링 단계에서 결정.

샤딩 도구

Vitess (YouTube에서 시작)

MySQL 위 샤딩 레이어. 애플리케이션 투명 (vt-gate 라우팅).

Citus (PostgreSQL)

PostgreSQL 확장. 분산 테이블 SQL로 관리.

MongoDB Sharding

MongoDB 자체 지원. mongos 라우터 + config 서버.

직접 구현

소규모 — 애플리케이션 코드에서 샤드 라우팅. 간단하지만 운영 부담.

def get_shard(user_id):
    return user_id % NUM_SHARDS

shard_id = get_shard(123)
db = get_db_connection(shard_id)
db.execute("SELECT * FROM users WHERE id = ?", (123,))

샤딩 vs 복제

5편(복제)와 보완 관계.

샤딩 = 데이터 분할 (쓰기 확장)
복제 = 데이터 복사 (읽기 확장 + HA)

운영 환경 = 샤딩 + 복제 조합
  shard1 (Primary + Replica × 2)
  shard2 (Primary + Replica × 2)
  shard3 (Primary + Replica × 2)

시험 직전 한 번 더 — 자주 헷갈리는 함정 모음

여기까지가 4편의 핵심입니다. 시험 직전 또는 실무에서 헷갈릴 때 다시 펼쳐 볼 수 있게 압축 노트로 마무리할게요.

  • 샤딩 = 여러 DB 서버에 분산
  • 단일 노드 한계 — CPU·RAM·Disk·연결·처리량
  • Partitioning (단일 DB) vs Sharding (여러 서버)
  • 샤딩 = 애플리케이션 라우팅 (DBMS 자동 X)
  • ACID 보장 어려움 — 2PC 필요
  • 3 전략 — Range / Hash / Geographic
  • Range = 범위 쿼리 빠름, Hot Spot 위험
  • Hash = 균등 분산, 범위 쿼리 X
  • Geographic = 지역별 / Directory = 매핑 테이블
  • 단순 modulo 해시 = Resharding 지옥
  • Consistent Hashing = 노드 추가/제거 시 1/N만 이동
  • Cassandra·DynamoDB·MongoDB·Redis Cluster 표준
  • Virtual Nodes (vnodes) = 분산 균등성 ↑
  • 단점 4가지 — Cross-Shard JOIN / 분산 트랜잭션 / Resharding / 운영 복잡도
  • Cross-Shard JOIN = 데이터 재구조화·앱 레벨·denormalization
  • 2PC = Phase 1 PREPARE / Phase 2 COMMIT, 느리고 장애에 약함
  • 대안 = Saga 패턴
  • Resharding 어려움 — 도구 (Vitess·Citus·MongoDB)
  • 샤딩은 마지막 수단 — 인덱스·Read Replica·캐시·파티셔닝 먼저
  • 샤딩 키 선정 = 가장 중요, 거의 되돌릴 수 없음
  • 좋은 키 — 카디널리티 높음·자주 WHERE·불변·JOIN 효율
  • SaaS = tenant_id / 소셜 = user_id
  • 도구 — Vitess (MySQL) / Citus (PostgreSQL) / MongoDB
  • 샤딩 = 쓰기 확장 / 복제 = 읽기 확장 + HA (보완 관계)

시리즈 다른 편

공식 문서: Vitess Architecture / Citus Documentation 에서 더 깊이.

다음 글(5편)에서는 복제 — Master-Slave / Multi-Master / 동기 vs 비동기 / Read Replica 설계까지 풀어 갑니다.

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!