데이터베이스 용어 사전
분산sharding · 수평 분할 · 샤드 키 · 일관된 해싱

샤딩

데이터를 키로 쪼개 여러 노드에 나누는 것. 쓰기와 용량까지 확장되지만 조인과 트랜잭션을 포기한다.

데이터를 샤드 키로 나눠 여러 노드에 분산하는 것. 복제가 못 하는 쓰기·용량 확장을 해결한다.

복제와의 역할 분담

복제같은 데이터를 복사한다→ 가용성 · 읽기 확장
샤딩데이터를 쪼갠다→ 쓰기 확장 · 용량 확장
  • 실제 시스템은 둘을 함께 쓴다 (각 샤드를 다시 복제한다)

샤드 키 선택이 전부다

좋은 샤드 키

  • 값이 고르게 분산된다
  • 대부분의 질의가 한 샤드로 간다

나쁜 샤드 키가 만드는 것

  • 핫스팟 — 한 샤드에만 트래픽이 몰린다 (예: 국가 코드로 샤딩했는데 90%가 한 나라)
  • 교차 샤드 질의 — 여러 샤드에서 모아야 답이 나온다 (가장 느린 샤드에 묶인다)

범위 vs 해시

범위 샤딩 (날짜·ID 구간)

  • ✅ 범위 질의가 한 샤드에서 끝난다
  • ❌ 최신 데이터에 쏠린다 (오늘 자 샤드만 뜨겁다)

해시 샤딩 (hash(key) % N)

  • ✅ 고르게 분산된다
  • ❌ 범위 질의가 모든 샤드로 흩어진다

리밸런싱 — 단순 나머지 연산의 함정

  • hash(key) % 3 — → 노드를 4대로 늘리면 hash(key) % 4
    • 거의 모든 키의 목적지가 바뀐다 → 전체 데이터 이동

일관된 해싱(consistent hashing)

  • 링 위에 노드를 배치해, 노드 하나 추가 시
  • 인접 구간만 이동한다 → 이동량 최소화

무엇을 포기하는가

-- 교차 샤드 조인 — 샤드가 다르면 DB 가 조인해 줄 수 없다
SELECT * FROM orders o JOIN member m ON o.member_id = m.id;
-- → 애플리케이션이 두 번 조회해 메모리에서 합치거나,
--   회원 정보를 각 샤드에 복제해 두거나(반정규화),
--   member_id 를 샤드 키로 삼아 같은 샤드에 놓는다

-- 교차 샤드 트랜잭션 — 원자성이 공짜가 아니다
-- → 2PC(느리고 블로킹) 또는 Saga(보상 트랜잭션)

샤딩은 조인과 분산 트랜잭션을 포기하거나 비싸게 사는 거래다. 그래서 순서가 있다.

  • ① 인덱스·쿼리 튜닝
  • ② 읽기 복제본 추가
  • ③ 수직 분할 (테이블 단위로 DB 분리)
  • ④ 캐시
  • ⑤ 그래도 안 되면 샤딩

면접 함정

  • "샤딩하면 성능이 좋아진다" → 단일 샤드로 끝나는 질의만 그렇다. 교차 샤드 질의는 오히려 느려진다.
  • "샤드 키는 나중에 바꾸면 된다" → 전체 재분배라 사실상 서비스 이전 수준의 작업이다.

실제로 어떻게 구현하나

  • ① 애플리케이션 레벨 라우팅
    • 샤드 키로 어느 DataSource 를 쓸지 코드가 정한다. 단순하지만 전부 직접 만든다
  • ② 프록시 계층
    • ProxySQL · Vitess(MySQL) · Citus(PostgreSQL 확장) 가 라우팅을 대신한다
  • ③ 네이티브 분산 DB
    • CockroachDB · TiDB — 처음부터 분산으로 설계된 제품을 쓴다
-- Citus: PostgreSQL 을 그대로 두고 분산 테이블로 만든다
SELECT create_distributed_table('orders', 'tenant_id');
-- tenant_id 가 같은 행은 같은 노드에 모인다 → 테넌트 안의 조인은 로컬로 끝난다

마지막 줄이 샤드 키 설계의 정석이다 — 함께 조회되는 데이터를 같은 샤드에 모은다(colocation).

전역 유일성이 깨진다

AUTO_INCREMENT 는 샤드마다 따로 돈다 → id 가 겹친다

대안

  • 샤드별 시작값을 다르게 (1, 2, 3... / 1001, 1002...)
  • UUIDv7 · ULID (시간순 정렬 + 전역 유일)
  • Snowflake ID (타임스탬프 + 노드ID + 시퀀스)

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 분산 DB — 복제·샤딩·CAP·일관성·2PC/Saga