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문제를 먼저 풀어볼 수도 있어요.