Foundry
데이터베이스
심화
핵심

샤딩

수평 분할, Cross-shard 제약

샤딩 (Sharding)

핵심 개념

하나의 대규모 테이블을 여러 DB 서버에 수평 분할하는 것.

[단일 DB]
orders 테이블: 1억 건 → 느림!

[샤딩 후]
Shard 1: user_id 1~1000만 (2500만 건)
Shard 2: user_id 1001~2000만 (2500만 건)
Shard 3: user_id 2001~3000만 (2500만 건)
Shard 4: user_id 3001만~ (2500만 건)

→ 각 서버가 25%만 담당!

샤딩 키 전략

전략방법장점단점
범위 기반user_id 1~N구현 간단핫스팟 가능
해시 기반hash(user_id) % N균등 분산범위 쿼리 어려움
디렉토리 기반매핑 테이블 조회유연함매핑 테이블 병목

해시 기반 샤딩 예시

user_id = 12345
shard = hash(12345) % 4 = 1
→ Shard 1에 저장/조회

[라우팅]
App → Shard Router
      → hash(key) % N
      → 해당 Shard로 전달

주의할 점

Cross-Shard JOIN 불가
  → user_id=1과 user_id=2000만의
    주문을 JOIN하려면?
  → 애플리케이션 레벨에서 처리

Shard 추가 시 재분배 필요
  → Consistent Hashing으로 완화
  → 전체 데이터 이동 최소화

트랜잭션 범위 제한
  → 단일 Shard 내에서만 ACID 보장
  → 분산 트랜잭션은 복잡하고 느림

샤딩 vs 다른 전략

데이터 1000만 건 이하
  → 인덱스 최적화 + 읽기 복제본

1000만~1억 건
  → 파티셔닝 (단일 DB 내 분할)

1억 건 이상 or 쓰기 병목
  → 샤딩 (여러 DB 서버)
면접에서 이렇게 나옵니다

Q.샤딩이 필요한 시점은 언제인가요?

한 대로는 감당이 안 되고 다른 수단을 다 써본 뒤입니다. 샤딩은 운영 복잡도가 크게 오릅니다.

순서수단
1인덱스와 쿼리 개선
2캐시 도입
3읽기 복제본 추가
4서버 사양 상향
5테이블 파티셔닝
6샤딩

3번까지로 읽기는 대부분 해결됩니다. 샤딩이 필요한 것은 쓰기가 한 대의 한계를 넘을 때입니다. 복제본을 늘려도 쓰기는 리더 한 곳으로 모이기 때문입니다.

그 밖의 신호로는 단일 테이블이 수억 행을 넘어 인덱스가 메모리에 안 들어가는 경우, 백업과 복구 시간이 감당 안 되는 경우가 있습니다.

흔한 실수: 데이터가 많아지면 바로 샤딩을 떠올리는 것. 조인과 트랜잭션이 샤드를 넘으면 어려워지므로, 미룰 수 있으면 미루는 것이 좋습니다.

Q.샤딩 키를 잘못 선택하면 어떤 문제가 생기나요?

문제원인증상
편중값이 고르지 않다한 샤드만 포화되고 나머지는 논다
핫스팟특정 값에 트래픽이 몰린다인기 사용자나 인기 상품이 한 샤드로
재분배 비용나머지 연산 기반샤드 수를 바꾸면 대부분의 키가 이동한다
교차 샤드 조회조회 조건이 샤드 키가 아니다모든 샤드에 물어봐야 한다
user_id % 100     지역 코드가 앞에 오는 id 면 특정 샤드에 몰린다
hash(user_id) % 100   고르게 흩어진다

키 선택의 기준은 조회 조건에 그 키가 들어가는가입니다. 메시지를 room_id 로 샤딩하면 방 단위 조회가 한 샤드에서 끝납니다. user_id 로 샤딩하면 같은 방의 메시지가 흩어집니다.

흔한 실수: 고르게 나누는 것만 보는 것. 분포가 고르더라도 조회가 매번 전 샤드를 훑으면 샤딩의 이점이 사라집니다.

Q.Cross-Shard JOIN이 필요한 상황은 어떻게 해결하나요?

샤드를 넘는 조인은 DB 가 대신 해주지 않으므로 설계로 피하거나 애플리케이션에서 조합합니다.

방법내용대가
같은 샤드에 모은다함께 조회되는 데이터를 같은 키로 샤딩키 설계가 어려워진다
애플리케이션 조합각 샤드에서 가져와 코드에서 합친다왕복이 늘고 페이징이 어렵다
참조 데이터 복제작고 잘 안 바뀌는 표를 모든 샤드에 둔다갱신을 전 샤드에 전파해야 한다
조회 전용 저장소검색 엔진이나 분석 DB 에 합쳐 둔다동기화 지연이 생긴다

첫 번째가 가장 근본적입니다. 주문과 주문 항목을 같은 user_id 로 샤딩하면 그 조인은 한 샤드 안에서 끝납니다.

정렬과 페이징이 특히 어렵습니다. 전 샤드에서 상위 N개를 각각 받아 합치고 다시 정렬해야 하며, 깊은 페이지일수록 비용이 커집니다.

흔한 실수: 샤딩 후에도 기존 조인 쿼리를 그대로 쓰려는 것. 샤딩을 도입하는 순간 데이터 접근 방식을 함께 바꿔야 합니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

데이터베이스 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.