본문으로 건너뛰기
김신건의 로그

[DB] Sharding vs Partitioning: 수평 확장의 두 얼굴

· 수정 · 📖 약 3분 · 950자/단어 #sharding #partitioning #scaling #database
Sharding, Partitioning, horizontal sharding, vertical partitioning, shard key, consistent hashing, Citus, Vitess

정의

PartitioningSharding
범위한 DB 안여러 DB 노드
목적큰 테이블 관리수평 확장 (write/storage)
투명성DB 가 처리보통 애플리케이션 인지
PostgreSQL PARTITION BYCitus, Vitess, MongoDB

둘 다 “데이터를 여러 조각으로 나눈다”. 경계DB 노드 안인지 밖인지 차이.

Partitioning (한 DB 안)

-- PostgreSQL: 시간 기준 range partition
CREATE TABLE events (
  id BIGSERIAL,
  created_at TIMESTAMPTZ,
  body JSONB
) PARTITION BY RANGE (created_at);

CREATE TABLE events_2026_06 PARTITION OF events
  FOR VALUES FROM ('2026-06-01') TO ('2026-07-01');

CREATE TABLE events_2026_07 PARTITION OF events
  FOR VALUES FROM ('2026-07-01') TO ('2026-08-01');
종류의미
Range시간, 숫자 범위
List미리 정한 값 (region 등)
Hash해시 (균등 분포)

장점:

  • 큰 테이블 → 작은 partition (VACUUM, index 작음)
  • 오래된 partition drop = 빠른 보관 정리
  • partition pruning = WHERE 조건이 partition 키면 그것만 스캔

Sharding (여러 DB 노드)

flowchart TB
    Client --> Router[Router / Coordinator]
    Router -->|shard_key % N| S1[(Shard 1)]
    Router -->|shard_key % N| S2[(Shard 2)]
    Router -->|shard_key % N| S3[(Shard 3)]

Shard Key 선택

키 선택결과
user_id hash고른 분포, 한 user 가 한 shard
created_at rangehot shard (최근만 트래픽)
tenant_id멀티 테넌트. 큰 테넌트 = hot
geographicdata residency

IMPORTANT

Shard key 는 바꾸기 어렵다. 모든 query 가 shard key 포함 가능한지 먼저 검토.

Consistent Hashing

자세한 건 Load Balancer 의 consistent hashing 절.

flowchart LR
    Ring((Hash Ring)) --> N1[Node A]
    Ring --> N2[Node B]
    Ring --> N3[Node C]
    Key1["hash(user:42)"] -->|시계방향| N2

노드 추가/제거 시 N/M 만 재분배. Cassandra, DynamoDB, Redis Cluster 의 토대.

Cross-shard Query 의 비용

sequenceDiagram
    Client->>Router: SELECT count(*) FROM users
    par fan-out
        Router->>S1: SELECT count(*)
        Router->>S2: SELECT count(*)
        Router->>S3: SELECT count(*)
    end
    S1-->>Router: 1234
    S2-->>Router: 1567
    S3-->>Router: 1198
    Router->>Router: SUM
    Router-->>Client: 3999
쿼리비용
WHERE shard_key = X1 shard
WHERE shard_key IN (X, Y)2 shard
WHERE other_field = ...전 shard fan-out
JOIN cross-shard매우 비쌈 (피하기)
GROUP BY cross-shardrouter 가 merge

CAUTION

대부분 쿼리가 shard key 포함 안 됨 = 디자인 실패. shard key 결정 전에 access pattern 정의.

Vitess (MySQL sharding) 아키텍처

flowchart TB
    App[App] --> VTGate["VTGate (router)"]
    VTGate --> VTTablet1[VTTablet 1]
    VTTablet1 --> MySQL1[(MySQL)]
    VTGate --> VTTablet2[VTTablet 2]
    VTTablet2 --> MySQL2[(MySQL)]
    VTGate --> Topo["Topology Service<br/>(etcd / Zookeeper)"]
  • YouTube 가 만들고 기여.
  • MySQL 호환 (Vitess client 가 MySQL 프로토콜).
  • re-sharding 자동화.

Citus (PostgreSQL extension)

SELECT create_distributed_table('events', 'user_id');
SELECT create_reference_table('countries');   -- 모든 노드 복제
  • PostgreSQL 의 extension 으로 동작.
  • PG 의 모든 기능 + sharding.
  • Microsoft Azure Cosmos DB for PostgreSQL 이 기반.

다른 sharding 전략

전략의미
Hash-basedhash(key) % N. 균등하지만 N 변경 어려움
Range-based키 범위. hot shard 위험
Directory-basedlookup table. 유연 + 단일 장애
Consistent hashhash ring. N 변경 friendly

Re-sharding

shard 추가/제거 시 데이터 이동. 가장 어려운 운영.

flowchart LR
    Old[기존 3 shard] -->|N=4 추가| Migrate[데이터 이동]
    Migrate --> New[4 shard 분배]
    Note["traffic 처리 *지속* 가운데<br/>일관성 유지 어려움"] -.-> Migrate
  • 온라인 re-sharding몇 주 ~ 몇 달 운영.
  • Vitess, Citus, MongoDB 가 자동 도구 제공.
  • 수동 sharding (애플리케이션 레벨)매우 고통.

흔한 함정

WARNING

  1. Sharding 너무 일찍 = 운영 비용 폭증. 수직 확장 + replica수십 TB 까지 가능.
  2. Cross-shard transaction = 2PC 또는 saga 필요. 비용 큼.
  3. Hot shard 무시 = 한 노드만 100% CPU. shard key 재선택 필요.
  4. Partition pruning 작동 안 함 = partition key 가 WHERE 에 없으면 모든 partition 스캔.

Shard 전략 선택 가이드

flowchart TD
    Start["시작: 데이터 분산 필요?"] -->|"단일 DB 안"| P[Partitioning 검토]
    Start -->|"여러 DB 노드 필요"| S[Sharding 검토]
    P -->|"시간 기준"| PR[Range Partition]
    P -->|"균등 분산"| PH[Hash Partition]
    P -->|"지역 / 카테고리"| PL[List Partition]
    S -->|"주요 쿼리에 shard key 포함 가능?"| SK{"shard key 결정"}
    SK -->|"user_id"| SH["Hash-based Shard"]
    SK -->|"날짜 / 범위"| SR["Range-based Shard"]
    SK -->|"멀티 테넌트"| ST["Tenant-based Shard"]

NOTE

수직 확장 + replica 가 수십 TB 까지 가능. shard 도입 전 replica read + connection pooling + 인덱스 최적화 먼저 시도.

Hot Shard 탐지와 해소

한 shard 에 트래픽 집중 = 전체 성능 병목.

-- Citus: shard 별 크기 확인
SELECT shardid, shard_size(shardid) AS size_bytes
FROM pg_dist_shard
ORDER BY size_bytes DESC;
증상원인해결
특정 shard CPU 100%shard key 쏠림key 재설계 / sub-sharding
write 지연 특정 시간대만range shard 의 최신 hothash shard 전환
특정 테넌트 slow대용량 테넌트해당 테넌트 전용 shard

TIP

Consistent hashing 에 virtual node 를 많이 두면 한 노드 추가 시 더 균등하게 재분배.

Partition 관리 자동화

PostgreSQL 의 pg_partman 을 이용한 자동 파티션 생성:

-- pg_partman 설정
SELECT partman.create_parent(
    p_parent_table => 'public.events',
    p_control      => 'created_at',
    p_type         => 'range',
    p_interval     => 'monthly',
    p_premake      => 3              -- 3개월 미리 생성
);

-- 유지보수 함수 (cron 으로 실행)
SELECT partman.run_maintenance();

오래된 파티션 드롭:

UPDATE partman.part_config
SET retention = '6 months', retention_keep_table = false
WHERE parent_table = 'public.events';
  • 오래된 partition dropTRUNCATE 급 속도, DELETE 와 비교 불가.
  • VACUUM / ANALYZE 도 파티션 단위, 전체 테이블 잠금 없음.

Partition Pruning 검증

-- partition pruning 작동 확인
EXPLAIN ANALYZE
SELECT * FROM events
WHERE created_at >= '2026-06-01' AND created_at < '2026-07-01';
-- "Seq Scan on events_2026_06" 만 나타나야 함
-- "Seq Scan on events" 가 나타나면 pruning 미작동
EXPLAIN 결과의미
Seq Scan on events_2026_06pruning 정상 작동
Seq Scan on events (partitions: ...)pruning 실패, 쿼리 수정 필요
Bitmap Heap Scan on events_2026_06인덱스 사용 + pruning

운영 체크리스트

  • shard key 결정 전 access pattern 목록 작성
  • 전체 쿼리 중 shard key 포함 비율 70% 이상 확인
  • cross-shard JOIN 최소화 (비정규화 또는 application-side join)
  • re-sharding 시뮬레이션 테스트 환경에서 수행
  • Hot shard 모니터링 대시보드 (Grafana + Prometheus)
  • Partition pruning 동작 EXPLAIN ANALYZE 로 확인
  • pg_partman 또는 automated retention 정책 설정

관련 위키

이 글의 용어 (8개)
[DB] Cassandra: LSM-tree, quorum, eventually consistentdatabase-internals
정의 Apache Cassandra = 마스터리스 (peer-to-peer) 분산 KV 스토어. write 우선, eventually consistent, 수평 무한 확장. 20…
[DB] DynamoDB: PK + SK, single-table design, GSI / LSIdatabase-internals
정의 DynamoDB 는 AWS 의 fully managed key-value + document NoSQL. low-latency, infinite scale, schemale…
[DB] MongoDB: 문서 DB, WiredTiger, replica set, aggregationdatabase-internals
정의 MongoDB 는 BSON (binary JSON) 문서 기반 NoSQL DB. schema-less 라기보다 flexible schema. 2026 시점 Atlas (ma…
[DB] MySQL / InnoDB: clustered index, redo log, MVCCdatabase-internals
정의 MySQL + InnoDB (기본 스토리지 엔진) 의 clustered index + redo log 기반 행 기반 RDBMS. 웹 / SaaS 의 가장 흔한 backbon…
[DB] PostgreSQL: 프로세스 모델, MVCC, WAL, 확장성database-internals
정의 PostgreSQL 은 오픈소스 ORDBMS. 1986 UC Berkeley POSTGRES 의 후예. MVCC, 확장 가능 타입, JSONB, full-text searc…
[DB] Transaction Isolation Levels: 완벽 가이드database-internals
정의 Transaction Isolation Level (트랜잭션 격리 수준) = 동시에 실행되는 여러 트랜잭션이 서로의 변경을 어디까지 볼 수 있는지 규정하는 수준. ACID …
[Distributed Systems] Consensus: Raft, Paxosdistributed-systems
정의 Consensus (합의): 여러 노드가 같은 값에 동의 하는 분산 알고리즘. CAP 의 C 보장의 기반. 용도: - Leader election: 1개 leader 선출 …
[Network] Load Balancer: L4 vs L7, 알고리즘, sticky sessionnetwork
정의 Load Balancer 는 트래픽을 여러 백엔드로 분산 하는 인프라. 수평 확장 + 가용성 + 무중단 배포 의 토대. L4 vs L7 | 구분 | L4 (Transport…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기