트래픽이 커진 서비스에서 성능 문제를 겪을 때 많은 팀이 먼저 인스턴스를 늘립니다. 하지만 특정 테이블/파티션에 트래픽이 몰리는 구조라면 수평 확장만으로는 한계가 빨리 옵니다. 이때 필요한 판단이 샤딩이고, 더 중요한 건 처음 키를 어떻게 고르는지입니다.
샤딩은 DB를 나누는 기술이 아니라, 미래의 운영 복잡도와 장애 반경(blast radius)을 미리 설계하는 선택입니다. 키를 잘못 고르면 조회는 느려지고, 핫샤드가 생기고, 결국 리샤딩이라는 고비용 작업이 반복됩니다.
이 글에서 얻는 것
- 샤딩 키를 고를 때 자주 놓치는 기준(분포·조회 패턴·재배치 비용)을 숫자 중심으로 판단할 수 있습니다.
- “지금 리샤딩해야 하는가"를 감으로 결정하지 않고, 운영 지표 임계치로 결정할 수 있습니다.
- 다운타임 없이 리샤딩을 진행할 때 필요한 단계(이중 쓰기, 검증, 컷오버, 롤백)를 실무 순서대로 가져갈 수 있습니다.
핵심 개념/이슈
1) 샤딩 키 품질은 3가지를 동시에 봐야 한다
좋은 샤딩 키는 보통 아래 3가지를 함께 만족합니다.
- 분포 균등성: 특정 샤드가 과도하게 뜨거워지지 않는가
- 조회 지역성(Locality): 주요 쿼리가 단일 샤드에서 끝나는가
- 시간 안정성: 특정 시간대/이벤트에서 편향이 급격히 커지지 않는가
예를 들어 tenant_id는 멀티테넌트 서비스에서 지역성이 좋지만, 대형 테넌트가 존재하면 핫샤드 위험이 큽니다. 반대로 랜덤 UUID는 분포는 좋지만, 범위 조회/집계가 비싸질 수 있습니다. 이 판단은 멀티테넌시 전략, 정합성 모델과 같이 봐야 실수가 줄어듭니다.
2) 리샤딩 필요 신호는 “느낌"이 아니라 임계치로 본다
실무에서 많이 쓰는 신호는 아래와 같습니다.
- 가장 뜨거운 샤드의 QPS가 평균 샤드 대비 2.5배 이상이 7일 이상 지속
- 샤드별 저장 용량 편차가 3배 이상
- p95 지연이 특정 샤드에서만 SLA(예: 120ms)를 20% 이상 초과
- 운영 이슈(타임아웃/락 대기/재시도)가 상위 1~2개 샤드에 집중
이 조건 2개 이상이 겹치면 “최적화"보다 “재분배"를 먼저 검토하는 편이 안전합니다.
3) 샤딩 전략은 1회 선택이 아니라 진화 전략이다
초기에는 해시 샤딩이 단순하고 빠릅니다. 하지만 성장하면 리샤딩 유연성이 중요해집니다.
- Range 샤딩: 범위 조회 유리, 핫스팟 위험 큼
- Hash 샤딩: 분포 유리, 범위 조회/정렬 비용 상승
- Composite 키(예: tenant_id + hash(user_id)): 지역성과 분포 절충
핵심은 “지금 빠른 방식"보다, 1년 뒤 재배치 비용이 낮은 방식을 고르는 것입니다. 확장 단계에서는 Online DDL + Expand/Contract 패턴과 결합해야 다운타임 리스크를 줄일 수 있습니다.
4) 리샤딩 실패의 절반은 데이터 복제보다 검증에서 발생한다
데이터 이동 자체는 도구로 처리됩니다. 진짜 어려운 건 아래입니다.
- 이중 쓰기 중 순서 역전/누락 검증
- 컷오버 시 읽기 라우팅 일관성 유지
- 재처리 중복 방지(멱등성)
그래서 리샤딩은 마이그레이션 작업이 아니라 검증 파이프라인 작업에 가깝습니다. 멱등성 설계, DB 락 경합 대응을 함께 준비해야 합니다.
실무 적용
1) 샤딩 키 결정 프레임(우선순위)
우선순위를 고정하면 팀 논쟁 비용이 크게 줄어듭니다.
- SLA 보호: 주요 API p95/p99를 단일 샤드에서 안정적으로 만족 가능한가
- 운영 단순성: 라우팅 규칙이 명확하고 온콜이 추론 가능한가
- 재배치 용이성: 샤드 수 증가(예: 8→16) 시 재해시/재분배가 예측 가능한가
- 비용: 저장/복제/백업 비용이 예산 내에서 유지되는가
비용보다 SLA/운영 단순성을 먼저 두는 편이 장기적으로 싸게 먹힙니다.
2) 리샤딩 실행 절차(다운타임 최소화)
- 1단계: 준비
- 샤드 매핑 테이블 버전 관리(
v1,v2) - 읽기/쓰기 라우터에서 버전별 라우팅 지원
- 샤드 매핑 테이블 버전 관리(
- 2단계: 백필(Backfill)
- 배치 복제 + 체크섬 검증
- 실패 배치는 재시도 큐로 분리
- 3단계: 이중 쓰기
- old/new 샤드 동시 반영
- 쓰기 성공 기준:
old=success AND new=success(초기)
- 4단계: 읽기 컷오버
- 트래픽 5% → 25% → 50% → 100% 단계 전환
- 단계별 30분 안정화 관찰
- 5단계: 정리
- old 샤드 read-only → 보관 기간 후 제거
3) 의사결정 기준(숫자·조건)
- 컷오버 단계 승격 조건
- 데이터 정합성 검증 통과율 99.99% 이상
- new 샤드 p95 지연이 old 대비 +15% 이내
- 오류율(5xx/timeout) 0.3% 미만
- 즉시 롤백 조건
- 금액/재고/권한 등 핵심 도메인 불일치 1건 이상
- 10분 평균 오류율 1% 초과
- 락 대기 시간 p95가 기준 대비 2배 초과
중요한 건 롤포워드보다 롤백 경로를 먼저 완성하는 것입니다.
4) 운영 지표 최소 세트
- 샤드별 QPS, CPU, storage growth rate
- 샤드별 p95/p99 지연
- 샤드별 오류율 + 재시도율
- 이중 쓰기 불일치율
- 백필 처리량/지연/실패율
이 지표가 없으면 리샤딩은 “진행 중"인데 아무도 상태를 설명하지 못하는 프로젝트가 됩니다.
트레이드오프/주의점
초기 과설계 위험
아직 트래픽이 작을 때 샤딩부터 들어가면 개발 속도가 크게 느려집니다. 단일 DB로 버틸 수 있는 기간을 숫자로 먼저 계산하세요.분포 최적화 vs 조회 비용 충돌
분포만 보고 랜덤 키를 택하면 조인/집계가 비싸질 수 있습니다. 핵심 조회 3개를 먼저 고정하고 키를 선택해야 합니다.이중 쓰기 구간의 운영 피로
장애 가능성이 가장 큰 기간입니다. 온콜/관제/롤백 책임자를 명확히 지정하지 않으면 컷오버가 길어집니다.샤딩 후 쿼리 품질 저하
애플리케이션이 팬아웃 쿼리를 남발하면 샤딩 전보다 느려질 수 있습니다. 샤딩은 DB 문제이면서 동시에 API 설계 문제입니다.
체크리스트 또는 연습
실무 체크리스트
- 샤딩 키 후보별 분포 시뮬레이션(최근 30일 데이터)을 수행했다.
- 핵심 API 10개 중 단일 샤드 처리 비율을 측정했다.
- 리샤딩 승격/롤백 임계치를 문서화했다.
- 이중 쓰기 불일치 탐지와 재처리 멱등성을 검증했다.
- 컷오버 당일 운영 책임(의사결정자/온콜/커뮤니케이션)을 사전 지정했다.
연습 과제
- 현재 서비스의 상위 트래픽 엔드포인트 5개를 뽑고, 각각이 단일 샤드로 끝나는지/팬아웃이 필요한지 분류해보세요.
- 샤드 8개 기준에서 상위 1개 샤드 QPS가 평균 대비 2.5배일 때, 16샤드 리샤딩 후 기대 분산을 추정해보세요.
- “이중 쓰기 2일차에 불일치율 0.02% 발생” 상황에서 승격 유지/롤백 중 무엇을 선택할지 의사결정 문안을 작성해보세요.
💬 댓글