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개를 각각 받아 합치고 다시 정렬해야 하며, 깊은 페이지일수록 비용이 커집니다.
흔한 실수: 샤딩 후에도 기존 조인 쿼리를 그대로 쓰려는 것. 샤딩을 도입하는 순간 데이터 접근 방식을 함께 바꿔야 합니다.